dev-prune vs kondo, npkill, cargo-sweep, rimraf and a cron job
An honest comparison. Four of these are better than dev-prune at the thing they do; here is when each one is the right answer.
Most comparison pages are written to win. This one is not, because the tools below mostly do not overlap, and pretending they do would make it useless to the person reading it.
rimraf, del-cli, rm -rf
Use these when you are deleting one directory you are looking at. They
are faster than anything else, they need no setup, and there is no decision to make because
you have already made it. rimraf exists because rm -rf is not
portable to Windows and Node scripts need it to be; that is its whole job and it does it.
Nothing below is an improvement on rm -rf node_modules for the single-project
case.
kondo
Use it when you want to look at every heavy directory on the machine and decide
each one yourself, and you want that in one binary rather than one per language.
kondo is the closest thing to dev-prune that exists, it is older, it has more users, and on
the axis it was built for it is genuinely good: it walks a tree, recognises twenty-odd
project types, shows you what each one costs, and deletes what you confirm. There is a GUI
(kondo-ui), it is in winget, Homebrew, MacPorts and the Arch repositories, and
kondo --older 30d covers the common case in one line.
The difference is not coverage, it is what happens in the moment before a deletion. kondo's own README says it plainly, twice:
Kondo is essentially
rm -rfwith a prompt. Use at your own discretion. Always have a backup of your projects.
That is an accurate description and a reasonable design: you are the check, so the tool
does not need to be. dev-prune is built for the case where nobody is watching, which forces
a different set of choices — it runs npm ci --dry-run or
uv lock --locked or cargo metadata --locked first and keeps the
directory when that exits non-zero; it reads git log rather than file
timestamps, so a node_modules nobody has touched inside a repository you
committed to this morning is not a candidate; it records what it removed so
devp restore can put it back; and it schedules itself, which is the whole
point of the verification, because a background pass that guesses is a background pass that
eventually eats something.
Neither of those is better in the abstract. If you are going to sit there and approve each row, kondo's warning is honest and its coverage is broad and you should use it. If you want the machine cleaned on a timer and would rather be told “no” than be surprised, a prompt is not the safety mechanism you need.
npkill
Use it for a one-off sweep you want to supervise. It scans for
node_modules, sorts by size, shows last-modified dates, and you delete with the
arrow keys. For "I need 20 GB back this afternoon and I want to see every row before it
goes", it is the right tool and it is pleasant to use.
Where it stops: it is Node-only, it is interactive by design so it does not automate, and last-modified is a heuristic for safety rather than a check. That is a reasonable trade for a supervised sweep — you are the check.
cargo-sweep
Use it if your problem is one big Rust repository.
cargo sweep --time 30 removes stale artefacts from target/ while
leaving the current ones intact, so you reclaim most of the space and keep an
incremental build. Nothing else here does that; dev-prune's cargo adapter deletes
target/ whole, which is a blunter instrument. If Rust is where your disk goes,
cargo-sweep is better at this than dev-prune is.
Why target/ gets so big has the detail.
A find command in cron
Use it if you know exactly what you want deleted and it will not change.
Twelve lines of shell, no dependency, and it does precisely what you wrote. The failure mode
is that it does precisely what you wrote: it will delete the project you are mid-debug in,
and it will delete a node_modules whose lockfile no longer resolves, because
you did not write those checks and you were never going to.
dev-prune
Use it when you want the machine to stay clean without you supervising it, and you would rather be told "no" than be surprised. The differences that matter:
- It verifies before deleting. Every adapter runs the package manager's
own dry-run —
npm ci --dry-run,pnpm install --lockfile-only,uv lock --locked,cargo metadata --locked,bundle lock --check— and a non-zero exit means the directory stays. On the author's own machine, a recent pass refused 2 of 11 candidates: one repository had a webpack version innode_modulesthat was missing from the lockfile, and another had a package installed into.venvthatuv.lockdid not mention. Both would have been silently lost by any tool that deletes on a last-modified heuristic. - Thirty-five package managers, not one. npm, pnpm, yarn, bun, Deno;
uv, Poetry, PDM, Pipenv, venv, pixi; Go, Composer, Bundler, Mix, CocoaPods, Terraform,
all on by default. Cargo, Gradle, Maven, sbt, SwiftPM, Dart, .NET, Zig, Stack, Cabal,
_buildfor Mix, vcpkg, CMake and the game-engine import caches (Godot, Unity, Unreal, Defold, Cocos Creator) ship disabled, because their output is a compile rather than a download and that is a different price. - Idle-gated. Nothing is a candidate until its repository has gone without a commit or a working-tree change for a threshold you set.
- Hard safety rules with no override flag. It never crosses a
.gitboundary, never follows or deletes through a symlink, and writes its state atomically. There is no--forcethat turns those off, deliberately. - Undo.
devp restorereinstalls what the last pass removed, using the same lockfiles it verified.
What it is not: it is not interactive scanning (npkill is better), it is not surgical
about build artefacts (cargo-sweep is better), and it is not a one-liner for a directory in
front of you (rm -rf is better). It is a background process that keeps a machine
from filling up, and refuses rather than guessing.
curl -fsSL https://devprune.vkrishna04.me/install.sh | sh
devp init ~/Code
devp run --dry-run
Apache-2.0, a single Rust binary, no telemetry.
Common questions
What is the best alternative to npkill?
It depends what you are doing. For a supervised one-off sweep of node_modules, npkill is very good and hard to beat. For an unsupervised, recurring cleanup across many package managers with a lockfile check before each deletion, dev-prune is built for that case. For a single directory in front of you, rm -rf is faster than both.
How does dev-prune compare to kondo?
kondo is the closest comparable tool and it is older and more widely packaged. It scans for heavy project directories across about twenty project types and deletes what you confirm; its own README describes it as essentially rm -rf with a prompt. dev-prune is built to run unattended instead, so it does the things a prompt would otherwise be doing: it runs the package manager dry-run that matches each lockfile and keeps the directory if that fails, gates on git activity rather than file mtime, records what it deleted so devp restore can reinstall it, and schedules itself. Supervised one-off: kondo. Unattended and recurring: dev-prune.
Does dev-prune replace cargo-sweep?
No. cargo-sweep removes stale artefacts from target/ while keeping the current build, which is more precise than anything dev-prune does; dev-prune deletes target/ whole and only when you have opted the cargo adapter in. If Rust build output is your main problem, use cargo-sweep.
Why not just use a cron job with find?
You can, and for a machine whose layout never changes it is fine. The difference is that find deletes unconditionally: it will delete a node_modules whose lockfile no longer resolves, and the project you are debugging right now, because those checks are not something a find expression can express.