Every JavaScript project you install keeps its own node_modules folder, and it stays on disk long after you stop working on the project. Here is how to find all of them, see which are biggest and remove the ones you don't need.
node_modules holds a project's installed dependencies. It is created by npm install, yarn, pnpm install or bun install, and it can be recreated from the project's package.json and lockfile at any time.
It should not contain your own work. The exception is if you edited files inside node_modules by hand: those edits are lost when it is deleted.
Each one sits next to a package.json. A monorepo usually has one at the root and more inside each package, such as packages/web/node_modules.
Some node_modules folders are not project folders, and you should leave them alone:
npm root -g prints (for Homebrew's Node on Apple silicon, /opt/homebrew/lib/node_modules). Deleting it removes your globally installed command-line tools.~/.nvm/versions.~/.vscode/extensions, which ship their own node_modules.That is why the commands below search your project folders, not your whole home folder. Replace ~/Projects with wherever you keep code; you can list several folders, such as ~/Projects ~/Desktop.
find ~/Projects -type d -name node_modules -prune 2>/dev/null
-prune stops find from going inside each one, which would otherwise list thousands of nested node_modules folders that belong to packages. 2>/dev/null hides permission errors.
find ~/Projects -type d -name node_modules -prune -exec du -sh {} + 2>/dev/null | sort -hr
The total across all of them, in gigabytes:
find ~/Projects -type d -name node_modules -prune -print0 2>/dev/null | xargs -0 du -sk | awk '{s+=$1} END {printf "%.1f GB\n", s*1024/1e9}'
To list only folders that haven't changed in 90 days:
find ~/Projects -type d -name node_modules -prune -mtime +90 2>/dev/null
A folder's modification time changes when packages are added or removed, not when you run the project, so treat this as a rough hint about old projects rather than proof.
pnpm fills node_modules with hard links to files in its shared store. du reports the full size, but deleting a pnpm project's node_modules frees much less, because the same files are still in the store. The space comes back when you prune the store; see the package manager caches guide.
Stop any dev server, test watcher or editor task running in the project first.
One project:
rm -rf ~/Projects/old-app/node_modules
Every node_modules under a folder. Run the "find them all" command first and read the list, because this deletes immediately and skips the Trash:
find ~/Projects -type d -name node_modules -prune -exec rm -rf {} +
If you would rather be able to undo it, drag the folders to the Trash in Finder instead. Emptying the Trash can take a while, because node_modules folders contain a very large number of small files.
node_modules in any project that has a lockfile.dist, build and out folders. They are build output, but some projects ship or deploy straight from them, and you may have a build you haven't deployed yet. Don't sweep them up by name.package.json, lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lock), .env files and your source folders.Run the project's install command when you next work on it: npm install (or npm ci to install exactly what the lockfile says), yarn, pnpm install or bun install.
The install needs a network connection unless the package manager's cache already has every package. How long it takes depends on the number of dependencies and your connection. Without a lockfile, the install may resolve newer versions than you had before.
The free scan in SymbolSweep walks your project folders (~/Desktop, ~/dev, ~/Developer, ~/Projects, ~/Code, ~/repos, ~/workspace, ~/src, and folders directly in your home folder that contain a package.json, Cargo.toml or .git) up to six levels deep. It does not look inside ~/Library or hidden folders such as ~/.nvm.
node_modules is listed in the REINSTALL tier with its project name, and marked unused once the project has been idle for 14 days or more.node_modules/.cache build cache inside it is listed separately as SAFE.dist, build and out folders are listed as REVIEW with a warning, and move to the Trash only one at a time, after you confirm.Scanning is free and never deletes anything. Deleting needs a one-time $12 license for one Mac. Requires macOS 13 or later on Apple silicon. See how it works.
Yes, if the project has a package.json and ideally a lockfile. Running the install command recreates it. Only edits you made by hand inside node_modules are lost.
Not permanently. The project won't run until you install again, which needs a network connection unless your package manager's cache has the packages.
Run find ~/Projects -type d -name node_modules -prune to list them, check the list, then run the same command with -exec rm -rf {} + on the end.
pnpm hard-links packages from its shared store into each project. The data stays on disk in the store until you run pnpm store prune.