Find unused dependencies — conservative, zero-config, zero dependencies. Flags only packages referenced nowhere, so every result is safe to remove.
Project description
depsnap
Find the dependencies you can safely delete. Your package.json collects
cruft — a package you stopped importing six refactors ago is still installed,
still audited, still slowing npm install. depsnap finds the ones referenced
nowhere in your code, config, or scripts. Conservative by design, zero
config, zero dependencies.
pip install depsnap
depsnap
depsnap — 1 unused dependency in demo-app (of 3 checked)
● left-pad dependencies no import or script reference
Verify before removing — depsnap only flags names it found nowhere · 1 @types/* skipped.
Why another one
depcheck was the go-to for years, but it was archived in 2025
with a long tail of false-positive bugs — TypeScript type-only imports, subpath
imports, peer deps, @types/* stubs all getting wrongly flagged as "unused".
knip is the powerful successor, but it's a ~150-plugin tool built for big
codebases; sometimes you just want a five-second answer to "what's safe to
delete?"
depsnap takes the opposite bet from depcheck: instead of trying to prove a
dependency is used (and getting it wrong on edge cases), it only flags a
package when its name appears nowhere — no import, no require, no dynamic
import(), no string in a config file, no CLI in an npm script. Every result
is high-confidence removable.
That means it handles the cases depcheck botched, for free:
| Case | depcheck | depsnap |
|---|---|---|
import type { X } from 'pkg' |
often flagged unused | seen as used |
import 'pkg/subpath' |
sometimes missed | seen as used |
await import('pkg') |
sometimes missed | seen as used |
@types/* stubs |
flagged unused | skipped by default |
CLI used only in an npm script (tsc) |
flagged unused | seen as used (reads node_modules bins) |
| peer dependencies | flagged unused | not checked |
The trade-off is honest: depsnap won't catch a dependency you import but never actually call — that needs full reachability analysis. For that, reach for knip. depsnap is the fast first pass.
Usage
depsnap # check ./package.json against this project
depsnap path/to/pkg # check a project in another directory
depsnap --dev # also check devDependencies
depsnap --format json # machine-readable output
Try it on the bundled example after cloning:
python -m depsnap examples/demo # → flags left-pad
python -m depsnap examples/demo --dev # → also flags unused-dev-tool
How it works
- Reads
package.jsonfor your declared dependencies. - Walks your project (skipping
node_modules,dist,.git, etc.) and builds a corpus of every.js/.ts/.jsx/.tsx/.vue/.svelte/.json/.yaml/...and dotfile config — but neverpackage.jsonor a lockfile, since those list every dependency by name and would mask everything. - For each dependency, checks whether its name (with import-aware word
boundaries, so
lodash≠lodash-es) appears anywhere in that corpus, in the npmscripts, or as one of its installednode_modulesbin names. - Reports the ones that appear nowhere.
In CI
depsnap exits non-zero when it finds unused dependencies, so it can keep cruft
from creeping back in:
- run: npx depsnap --dev
| Exit code | Meaning |
|---|---|
0 |
no unused dependencies |
1 |
unused dependencies found |
2 |
error (no package.json, bad arguments) |
Options
--dev also check devDependencies (default: dependencies only)
--include-types also check @types/* packages (default: skipped)
--format text|json output format (default: text)
-v, --version
-h, --help
Scope
Single-package projects. Workspaces/monorepos aren't resolved across packages yet
(run it per-package). It reads package.json dependencies/devDependencies;
peerDependencies and optionalDependencies are intentionally left alone.
Also available for Node
npx depsnap
Same checks, same flags, same exit codes — depsnap on npm.
Note: depsnap reads
package.jsonand your source, so it works on any JS/TS project regardless of which language you install it from.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file depsnap-0.1.0.tar.gz.
File metadata
- Download URL: depsnap-0.1.0.tar.gz
- Upload date:
- Size: 11.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4f2a4e803e6be0e7fc4e02d0e6d081d2ab6560caada1b02e49575202db8be12
|
|
| MD5 |
051d43e5246c69e7ae0c6b438dbd7be1
|
|
| BLAKE2b-256 |
3adf5ffc5ea4926c630b79ab4513af7a9c4cca17e87923c0dae8e313bdef21ae
|
File details
Details for the file depsnap-0.1.0-py3-none-any.whl.
File metadata
- Download URL: depsnap-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8212cff1807b8189f1556bcc44c0d6fbc305c10f8e82426ca1c72a2f09bb7611
|
|
| MD5 |
c93bb8233141223a8775231dd89e7b89
|
|
| BLAKE2b-256 |
80f4f6365c44adac7c664c5e30a07f5d4263b6bf0b8f3e8454c0017c79ac4d64
|