Knip 6.39.0 vs depcheck 1.4.7 on 95 JS files: median wall 574.574 ms vs 581.463 ms (wash). Knip: 26 unused files, 8 unused deps, 56 unused exports. Depcheck: 8 unused deps only. Both agreed on unused production deps.
4 min read
On a 95-file JavaScript fixture, Knip 6.39.0 took a median 575 ms and depcheck 1.4.7 took 581 ms. Wall time was a wash. Knip also reported 26 unused files and 56 unused exports that depcheck does not look for, plus the same 8 unused production dependencies.
Short answer: leave depcheck for Knip when unused files and unused exports matter as much as unused packages. Keep depcheck when you only want a small package.json unused-deps check and nothing else. No affiliate links in this post.
src/ and scripts/ (libs, pages, dead orphans, a CLI entry). Production dependencies included used packages (lodash-es, chalk, ms) and eight deliberately unused ones (moment, left-pad, is-odd, bluebird, request, jquery, axios, and one more unused util package).knip 6.39.0 with knip.json entry points src/index.js and scripts/cli.js; depcheck 1.4.7 with defaults. Timed via direct node on each package bin.| Tool | Median | Runs (ms) | Unused deps | Unused files | Unused exports |
|---|---|---|---|---|---|
| Knip 6.39.0 | 575 ms | 570 / 562 / 586 / 582 / 575 | 8 | 26 | 56 |
| depcheck 1.4.7 | 581 ms | 712 / 683 / 563 / 581 / 581 | 8 | n/a | n/a |
On this fixture both CLIs finished in about 0.58 s. Depcheck answered the package.json question. Knip answered that plus unused files and unused exports. If your backlog is dead modules and dead exports, depcheck alone will not surface them.
Dead-code cleanup pairs with lint and format work. The Biome vs ESLint + Prettier post and the oxlint vs ESLint post are the related quality-gate decisions on this site; this post is the unused-code inventory step. Package install speed is a separate question covered in the pnpm vs npm vs Bun post.
depcheck is smaller and single-purpose. Teams that only gate on unused dependencies, and that already ignore unused files elsewhere, may not want Knip's broader report noise. Knip also needs entry and project globs; a wrong entry list can mark live files as unused.
Also expect to maintain an ignore list. Orphan scripts, intentional barrels, and generated clients often need explicit allow rules before Knip is green in CI. Re-run both tools on your own tree before deleting packages or files.
| Situation | My pick |
|---|---|
| You care about unused files and unused exports, not only packages | Switch to Knip; keep an ignore list |
| You only want unused dependencies in package.json | Keep depcheck |
| Monorepo with clear entry points already listed for Knip | Knip is the better fit to evaluate |
| CI already fails on any unused-export noise you cannot afford | Stay on depcheck, or adopt Knip with a tight ignore |
| First PR would delete 26 orphan files without review | Inventory with Knip, then delete in small batches |
Bottom line: on 95 files, Knip and depcheck both took about 0.58 s, and Knip also found 26 unused files and 56 unused exports. Who should not switch yet: teams that only want a package.json unused-deps gate. Everyone else cleaning dead modules should measure their own tree the same way.
How this was made: I built the fixture, ran interleaved Knip and depcheck on the ShopperCove test box, and kept the timing JSON; the write-up was drafted with AI help and checked against that output.
Lab evidence
Hands-on on ShopperCove box 5 Oct 2026 ~23:05-23:15 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 20.19.2). Fixture: 95 files under src/ and scripts/ (libs, pages, dead orphans, CLI entry). Used deps: lodash-es, chalk, ms. Eight unused production deps planted. Versions: knip 6.39.0 (knip.json entries src/index.js + scripts/cli.js); depcheck 1.4.7 defaults. Timed via direct node on package bins. Wall medians (5 interleaved after warmup): knip 574.574 ms (570.489/561.889/586.158/581.712/574.574); depcheck 581.463 ms (711.614/683.255/562.828/581.463/581.206). Findings: knip unused files 26, unused deps 8, unused exports 56 (exit 1); depcheck unused deps 8 (exit 255). Raw: /workspace/bench-knip/res-knip.json. Not tested: TS project references, monorepo workspaces, Next/Nuxt presets, unused types, Windows/macOS, false-positive rate on a production repo. No affiliate.
ESLint published v10.12.0 on 2 October 2026 as a minor release: documentation and TypeScript types for SourceCode#getText(), getLoc(), and getRange() now accept tokens and comments (matching runtime behavior), plus multiple rule fixes including astral/Unicode letter handling and autofix edge cases. npm latest confirmed 10.12.0; ShopperCove docs checklist only; no affiliate.
Summary5 Oct 20264 min read
Hands-on6 Oct 20269 min read
Hands-on6 Oct 20268 min read