Skip to content

How to Delete node_modules Recursively on a Mac

Delete node_modules recursively on a Mac with one find command: list and size every folder first, skip the ones you need, and clear npm and pnpm caches.

Updated · 7 min read

To delete node_modules recursively on a Mac, cd into your projects folder and run find . -type d -name node_modules -prune -exec rm -rf {} +. Run it without -exec rm -rf {} + first to list what will go. Every folder comes back with npm install or pnpm install, so stale projects are safe to clear.

TL;DR

cd ~/code   # your projects folder, never / or ~

# 1. List every node_modules folder, biggest first
find . -type d -name node_modules -prune -exec du -sh {} + | sort -hr

# 2. Delete them all
find . -type d -name node_modules -prune -exec rm -rf {} +
  • Scope it to the folder that holds your projects. Global tools and editor extensions also use node_modules.
  • The package manager caches (~/.npm, the pnpm store) are separate and have their own clean commands.
  • On pnpm, most of the space is in the store, not in each project.

Can I delete the node_modules folder?

Yes. node_modules is a build artifact. Your dependencies are defined by package.json and pinned by the lockfile (package-lock.json, pnpm-lock.yaml, yarn.lock or bun.lock), and reinstalling recreates the folder.

What you actually give up:

  • Time and bandwidth. The next install downloads anything that is not already in your package manager’s cache.
  • Native builds. Packages with native code may compile again on install.
  • Hand edits. Anything you changed directly inside node_modules is gone. Patches made with patch-package or pnpm patch are stored outside it and re-applied on install.
  • Offline work. If you are about to go offline, keep the projects you need.

Why node_modules takes up so much space

Every project gets its own dependency tree, including transitive dependencies, TypeScript type packages, prebuilt native binaries for your platform and build tools. A single React Native or Next.js project can reach several gigabytes.

With npm, each project’s node_modules holds real copies of every file. Ten projects on the same framework store that framework ten times. Git worktrees multiply it again, because each worktree usually gets its own node_modules. If you use worktrees, see how to remove and prune git worktrees.

How to find every node_modules folder

List them

cd ~/code
find . -type d -name node_modules -prune

-prune is the important part. It stops find from descending into a node_modules folder once it has found one, so you get only the top-level folder for each project, not the hundreds of nested node_modules inside it. It also makes the search much faster.

See how big each one is

find . -type d -name node_modules -prune -exec du -sh {} + | sort -hr

Get a single total

find . -type d -name node_modules -prune -print0 | xargs -0 du -sch | tail -1

Treat these numbers as an upper bound if you use pnpm or Bun. The section on APFS clones below explains why du can overcount.

Find only stale projects

To list folders whose top level has not changed in 30 days (roughly, projects you have not installed into for a month):

find . -type d -name node_modules -prune -mtime +30

A folder’s modification time changes when entries are added or removed directly inside it, which happens on install. It is a reasonable proxy for “not touched lately”, not a guarantee.

How to delete node_modules recursively

Delete all of them

After checking the list:

find . -type d -name node_modules -prune -exec rm -rf {} +

Delete only stale ones

find . -type d -name node_modules -prune -mtime +30 -exec rm -rf {} +

Move them to the Trash instead

Recent macOS versions include a trash command (check with which trash). It lets you undo the cleanup until you empty the Trash:

find . -type d -name node_modules -prune -exec trash {} +

Moving tens of thousands of small files to the Trash is slower than rm -rf, and the space is not freed until you empty it.

Delete node_modules in a single project

rm -rf node_modules

Where not to run it

Do not run these commands from / or from your home folder. node_modules folders also live in places your tools depend on, for example:

  • Global npm packages, such as /opt/homebrew/lib/node_modules (Homebrew Node) or ~/.nvm/versions/node/<version>/lib/node_modules (nvm)
  • Editor extensions, such as those under ~/.vscode/extensions or ~/.cursor/extensions
  • App bundles and other tools that ship their own JavaScript dependencies

Run find from the folder that holds your projects, such as ~/code or ~/Developer.

What about npkill?

npkill is an open-source interactive tool that does the same search and shows the results in your terminal. You move through the list and delete folders one at a time:

npx npkill

It is a good fit if you prefer choosing project by project. npx downloads the package from npm the first time you run it. The find commands above do the same job with nothing to install.

Clean the package manager caches too

Deleting node_modules does not touch the caches your package manager keeps so that reinstalling is fast. Those can be several gigabytes on their own.

npm

npm keeps its cache in ~/.npm (see npm config get cache), with package data in ~/.npm/_cacache.

du -sh ~/.npm
npm cache verify          # checks the cache and garbage-collects unneeded data
npm cache clean --force   # deletes the cache entirely

pnpm

pnpm store path   # e.g. ~/Library/pnpm/store/v10 with pnpm 10 on macOS
du -sh "$(pnpm store path)"
pnpm store prune  # removes packages no project references anymore

pnpm store prune is safe: it only removes unreferenced packages. Per pnpm’s own help, the cost is that future installs may need to download those packages again.

Yarn and Bun

On most setups, yarn cache clean clears Yarn’s cache and bun pm cache rm clears Bun’s global cache. Run yarn cache dir to see where Yarn keeps it before deleting.

Why pnpm saves space (and what APFS clones change)

pnpm stores each version of each file once, in a content-addressable store shared by all projects. A project’s node_modules does not get its own copies. pnpm’s default import method, auto, tries to clone files from the store first, falls back to hard links when cloning is not supported, and copies only as a last resort.

On a Mac, APFS supports clones (copy-on-write files). A clone looks like a normal, independent file, but it shares its data blocks with the original until one of them is modified. On our test Mac, files inside a pnpm project’s node_modules/.pnpm had a link count of 1 (stat -f %l), consistent with clones rather than hard links.

That has three practical consequences:

  • du and Finder overcount. Both report a clone’s full size, even though the blocks are shared with the store. Ten pnpm projects can each show 2 GB while together using little more than the store itself.
  • Deleting one pnpm project’s node_modules frees little. The shared blocks stay on disk as long as the store or another project still references them.
  • The real space is reclaimed by pruning the store, after removing the projects you no longer need.

Bun also uses clones on macOS by default on most setups, so the same caveat about du applies. npm writes real copies, so with npm, du is accurate and deleting node_modules frees what it reports.

node_modules and caches at a glance

Path What it is Safe to delete? How it comes back
<project>/node_modules Installed dependencies for one project Yes npm install, pnpm install, yarn, bun install
~/.npm/_cacache npm download cache Yes Refilled on next install
~/Library/pnpm/store pnpm content-addressable store Prune it; deleting it forces full re-downloads Refilled on next install
/opt/homebrew/lib/node_modules, ~/.nvm/.../lib/node_modules Global npm packages No, unless you mean to uninstall them Reinstall with npm i -g
Editor extension folders Extension dependencies No Reinstall the extension

For the rest of a developer Mac, see the guide to freeing up space on a Mac for developers. If Docker is part of your JavaScript workflow, shrinking Docker.raw is usually the next biggest win.

Do it in one click with DevCleanup

DevCleanup’s Projects screen finds every node_modules folder across your projects with its real size and lets you clear the ones you pick in one go. Sizes are real-space numbers: APFS clones and hard links are not double counted, so pnpm and Bun projects show what deleting them will actually free. DevCleanup never deletes a git repository, and every action is logged in History with how to restore it. Scanning is free; developer cleanup actions are part of Pro ($29 one-time).

Download DevCleanup

Frequently asked questions

Can I delete the node_modules folder?

Yes. node_modules is rebuilt from package.json and your lockfile by running npm install, pnpm install, yarn or bun install. You only lose time and bandwidth, plus any manual edits made directly inside node_modules.

What is the command to delete node_modules in every project?

From your projects folder, run find . -type d -name node_modules -prune -exec rm -rf {} +. Run the same find without the -exec part first to see exactly which folders it will remove.

Why is node_modules so big?

Every project installs its own full dependency tree, including transitive dependencies, TypeScript types, native binaries and build tools. With npm, each project has its own copy of every file, so ten projects using the same framework store it ten times.

Does deleting node_modules free space if I use pnpm?

Less than you might expect. pnpm keeps one copy of each file in a global store and links or clones it into each project, so most of the space lives in the store. Run pnpm store prune to remove packages no project references anymore.