Use npkill to find and delete old node_modules folders

By

npkill is a free terminal tool that finds every node_modules folder on your computer, shows its size and age, and deletes the ones you pick.

~~~

npkill is a free terminal tool that finds every node_modules folder inside a directory, shows how much space each one takes and how long ago you last touched the project, and deletes the ones you pick with one key.

I ran it in my ~/dev folder in October 2026. In about 13 seconds it found 128 node_modules folders, 58.68 GB in total. Over two runs I deleted all of them except the 9 that belong to projects I’m working on, and npkill reported 49.89 GB of space released.

You don’t have to install it. If you have Node.js on your computer, open a terminal in the folder that holds your projects and run:

npx npkill

npkill is open source under the MIT license, made by Nya García Gallardo and Juan Torres Gómez. It works on macOS, Linux and Windows.

Why node_modules folders get so big

Every JavaScript project keeps its dependencies in its own node_modules folder. npm gives each project its own copy of every package, so if ten projects use React, you have ten copies of React on your disk.

A fresh Vite and React app starts at about 53 MB, as I measured in my post about the size of node_modules. Real projects add a router and a database client, and the folder keeps growing.

Some tools make it much bigger. My biggest folder belongs to the Remotion project I use to render the intro videos for my posts, and it’s 7.6 GB. Of that, 7.3 GB is build cache. Remotion bundles the code of a video with webpack, and webpack keeps its cache in node_modules/.cache/webpack.

The real problem is old projects. You finish something, you move on, and its node_modules folder stays on your disk forever. Deleting it is safe, because npm install rebuilds it from package.json and the lockfile when you come back to the project.

How to run npkill

The simplest way is npx, which downloads the package and runs it. The first time, npx asks you to confirm the download:

npx npkill

If you’d rather have the npkill command always available, install it globally:

npm install -g npkill

By default npkill scans the folder you’re in and everything inside it. Use -d to start somewhere else:

npx npkill -d ~/dev

It needs a real terminal window to draw its interface, and it refuses to start in a very narrow one (60 columns or less).

The README on GitHub already describes the next version of npkill, with multi-select, a search mode and JSON output. As of October 2026 that version isn’t on npm yet. The latest npm release is from June 2024, and that’s the version npx npkill runs and the one this post describes. If a key or a flag from the README does nothing, that’s why.

Reading the list

npkill adds folders to the list as it finds them, then calculates two numbers for each one.

Size is the space the folder takes, in megabytes. Add -gb to see gigabytes, which is easier to read when the folders are big.

Last_mod is how many days ago you changed a file in that project, not counting node_modules. 772d means you haven’t touched the project in more than two years, so this column shows you which projects you abandoned.

At the top, Releasable space adds up every folder in the list, and Space saved counts what you deleted so far.

You do everything with the keyboard:

A deleted folder gets a [DELETED] label in the list. It doesn’t go to the Trash: on macOS and Linux npkill runs rm -rf on it, so it’s gone right away. For node_modules that’s fine, since npm install brings it back.

When you quit, npkill prints how much you freed:

Space released: 40.72 GB
Thanks for using npkill!

Sort by age to find old projects

The list comes in the order npkill finds the folders. Sort it with -s. This puts the projects you haven’t touched in the longest time at the top:

npx npkill -s last-mod

This puts the biggest folders at the top:

npx npkill -s size

You can also sort with -s path, which is alphabetical.

How I use npkill

The first time I used npkill was in December 2022, to clean up ~/www/old, the folder where my old website projects end up.

In October 2026 I ran it twice in ~/dev, where I keep my Mac apps, CLI tools and experiments.

In the first run, with a plain npx npkill, I deleted the node_modules of six showreel projects. Those are the Remotion projects that render the 30-second videos for my app launches, and each one had between 0.78 and 2.11 GB of node_modules. The six together freed 9.16 GB.

Then I ran it again sorted by age, in gigabytes:

npx npkill -gb -s last-mod

The top of the list was boilerplate projects and example apps from past Bootcamp editions, untouched for 500 to 770 days. I went down the list and deleted every folder except the ones I’m working on now. That was 113 more folders and 40.72 GB.

I kept 9 folders. The biggest is the 7.6 GB node_modules of the Remotion project that renders my post intro videos. I still use that project, and its build cache saves time on every render.

Each scan of ~/dev took about 13 seconds.

The folders marked with ⚠️

Some node_modules folders belong to apps, not to your projects. Visual Studio Code and Cursor extensions ship with their own node_modules, and so do some desktop apps built with Electron. Delete one of those and the extension or the app breaks until you reinstall it.

npkill can’t know which folder is which, so it guesses from the path. It marks a folder with ⚠️ when it sits inside a hidden folder (one whose name starts with a dot, like ~/.cursor), inside a Mac app in /Applications, or inside AppData on Windows. For those rows it doesn’t calculate the age, and shows xx instead.

On my Mac, ~/.cursor/extensions has 11 node_modules folders and ~/.vscode/extensions has 19. Leave those alone.

~/.npm/_npx has 115. That’s the npx cache, where npkill itself ends up after you run it with npx. Those are safe to delete, because npx downloads a package again the next time you run it.

You only see these folders when you scan a place that contains them, like your home folder. -f starts the scan from your home folder, and -x leaves out every folder npkill would mark with ⚠️:

npx npkill -f -x

Search for other folders

node_modules is the default, but -t searches for any folder name you give it:

npx npkill -t dist

dist and build hold build output in many JavaScript projects, vendor holds the dependencies of a PHP project installed with Composer, and target is where Rust puts its builds. Be careful with generic names, because some projects keep scripts in a folder called build, and npkill can’t tell the difference.

You can search for one name at a time. Names that start with a dot work too, like .next for the Next.js build folder, but npkill treats them as hidden folders. Every result gets a ⚠️ and no age, and -x hides all of them.

Exclude folders

-E skips folders. Put the names inside quotes, separated by commas:

npx npkill -E "clients, archive"

npkill matches these names as text anywhere in the path. -E "old" skips a folder called old, but it also skips a project called golden-app, because “golden” contains “old”. Pick names that don’t appear inside other names.

The same rule explains a default you might not expect. npkill always excludes .git, so a project folder called flavio.github.io never shows up in the list.

Delete everything at once

-D deletes every folder npkill finds, as soon as it has measured it. It’s made for cases like a backup folder full of copied projects, where you want every node_modules gone without picking them one by one.

Before it starts, npkill shows a warning and waits for you to press y. The warning recommends two things. Add -x so it skips the ⚠️ folders, because without it -D deletes those too. And try it first with --dry-run, which pretends to delete without touching anything:

npx npkill -d ~/backups -D -x --dry-run

When the list looks right, run the same command without --dry-run. Add -y if you don’t want to see the warning. npkill still opens its interface while it works, and you quit with q when it’s done.

Before you delete

If the project has a lockfile (package-lock.json, pnpm-lock.yaml or bun.lock), the next install gets the exact versions you had. If it doesn’t, npm picks the versions again from the ranges in package.json, and you may get newer ones. I explain how the lockfile works in this lesson of my free Node.js course.

Build caches stored in node_modules/.cache, like webpack’s, go away with the folder, so the first build after reinstalling is slower.

The size npkill shows can be bigger than the space you get back. npkill measures each folder with du. pnpm doesn’t copy packages into each project: it keeps one copy in a global store (on my Mac that’s ~/Library/pnpm/store/v10) and hard links the files into node_modules. Bun on macOS does something similar with copy-on-write clones of its cache. When you delete those folders, the files are still in the store, so you free much less than npkill reports.

To clean the store, run pnpm store prune, which removes the packages no project uses, or bun pm cache rm, which clears Bun’s cache. I explain how pnpm and Bun share packages in Managing node_modules efficiently with pnpm and Bun. Most of the projects I cleaned used npm, so most of my 49.89 GB was real space.

Can a coding agent run npkill?

Usually not. Coding agents tend to run commands without an interactive terminal, and the npm version of npkill refuses to start there. This is what it prints when a Cursor agent runs it:

Oh no! Npkill does not support this terminal (TTY is required). This is a bug, which has to be fixed. Please try another command interpreter (for example, CMD in windows)

If you want an agent to help with the cleanup, ask it to list the folders with find and du, then delete the ones you approve:

find ~/dev -name node_modules -type d -prune -exec du -sh '{}' +

It’s the same command from my post on removing all the node_modules folders, with du -sh in place of rm -rf. That post’s one-liner is also the alternative to npkill when you want to delete every node_modules under a folder and don’t need to see the list first.

Tagged: Node.js · All topics

Want me to talk about your product? You can sponsor this site.

~~~

Related posts about node: