You have more node_modules than you think, and they are all still there
Every JavaScript project leaves a node_modules folder behind. Across a few years of work that is routinely 30 to 80 GB of code you will never run again.
- node_modules
- Developer
- Cleanup
A single npm install on a modest React project writes somewhere between 200 MB and 700 MB into node_modules. That is fine. The problem is that it stays there forever, in every project you have ever cloned to look at, and nothing on the machine ever suggests removing it.
Count the project folders you have made in the last three years. Multiply by roughly 350 MB. That number is sitting on your drive right now, and almost none of it belongs to code you are still working on.
Why it gets so large
- Dependencies are not shared by default. With npm, each project gets its own full copy of every package, including the twelve copies of the same utility library that four of your dependencies each pull in at a different version.
- Nothing expires. A
node_modulesfrom a 2023 experiment is byte for byte as large today as the day it was installed. - It is invisible in Finder. Folders do not report their recursive size unless you ask, so a 900 MB project directory looks the same as a 3 MB one.
Finding all of them
From a terminal, this lists every node_modules under your home folder with its size, largest first:
find ~ -name "node_modules" -type d -prune -print0 2>/dev/null \
| xargs -0 du -sh 2>/dev/null \
| sort -rh \
| head -30The -prune matters: without it, find descends into every node_modules it has already matched and takes minutes instead of seconds. Expect the total to be higher than your guess.
Deleting them safely
The safety property that makes this different from most disk cleaning: node_modules is fully reproducible. It is derived entirely from package.json and the lockfile, both of which are in version control. Deleting it destroys nothing, and npm install rebuilds it exactly.
The one caveat worth stating: if a project has an uncommitted patch applied inside node_modules, whether by hand or through a tool like patch-package, that change is not reproducible from the lockfile. This is rare, and you would know if you had done it.
# Remove node_modules from projects untouched for 90 days
find ~ -name "node_modules" -type d -prune -mtime +90 -print0 2>/dev/null \
| xargs -0 rm -rfStopping it recurring
| Approach | What it saves | Cost |
|---|---|---|
| Switch to pnpm | Most of it. Packages are stored once and hard-linked into projects | A different lockfile, and a few packages assume npm's flat layout |
| Clear on a schedule | Everything older than the cutoff | A rebuild the next time you open an old project |
| Nothing, and clear manually twice a year | The same, in bursts | You have to remember |
pnpm is the real fix if you start many projects. Its content-addressable store keeps one copy of each package version on the machine and links it into every project that needs it, which is the deduplication npm does not do. For a machine with thirty JavaScript projects the difference is tens of gigabytes.
Free Mac's Dev tab groups every node_modules on the drive by project with sizes attached, alongside Xcode DerivedData and the other build caches, so this is one pass rather than four. Scanning is free. Clearing them from inside the app is the paid part, and the find command above does the same job.
Common questions
Is it safe to delete node_modules?
Yes. The folder is generated entirely from package.json and the lockfile, both of which are in version control, so npm install rebuilds it exactly. The only exception is a project with hand-applied patches inside node_modules that were never committed, which is rare and something you would remember doing.
How much space does node_modules use?
A typical React or Next.js project uses 200 to 700 MB. A monorepo with several packages can pass 2 GB. The figure that matters is the total across every project on the machine, which for a working developer after a few years is commonly 30 to 80 GB.
Does pnpm actually use less disk space than npm?
Substantially, once you have more than a few projects. pnpm keeps a single copy of each package version in a store on the machine and hard-links it into each project, so ten projects sharing a dependency store it once rather than ten times. npm copies it into every project independently.