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.

Updated 2026-09-20

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 -rf with 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 in node_modules that was missing from the lockfile, and another had a package installed into .venv that uv.lock did 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, _build for 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 .git boundary, never follows or deletes through a symlink, and writes its state atomically. There is no --force that turns those off, deliberately.
  • Undo. devp restore reinstalls 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.