Developer
Clear Developer Caches Without Breaking Builds
Developer storage is fragmented across package downloads, build output, SDKs, local databases, and per-project dependency trees. Some is reproducible, some depends on a lockfile and a registry that may later disappear, and some is unique local data. A safe cleanup proves which kind it found instead of assuming every dot folder is cache.
The global caches, by tool
Each package manager keeps a global store you can measure directly:
du -sh ~/.npm ~/.cargo ~/.cache/pip ~/Library/Caches/pip ~/.gradle 2>/dev/null | sort -h
- npm caches downloads in
~/.npm. Start withnpm cache verify; npm describes its cache as self-healing, sonpm cache clean --forceis mainly for deliberate space recovery or troubleshooting. - Cargo keeps registries and git checkouts under
~/.cargo, but that root can also contain installed binaries, configuration, and credentials. Use a purpose-built tool or inspect exact cache subdirectories. Never remove all of~/.cargo. - pip caches wheels in
~/Library/Caches/pip(or~/.cache/pip);pip cache purgeclears it. - pnpm and yarn keep their own stores;
pnpm store pruneandyarn cache cleanclear them. - Gradle and Maven (
~/.gradle,~/.m2) can be huge on Android and JVM Macs. Stop their daemons first. A Maven repository may contain locally built or private artifacts that cannot be downloaded again, so inspect it rather than deleting the entire repository by default.
The cost can include a large download, a native rebuild, or a failed historical build when a registry version is gone. Verify the lockfile and source of each dependency before calling a store reproducible.
The scattered node_modules problem
The bigger surprise is usually not a single cache but the node_modules folders
spread across every JavaScript project you have ever touched. Each is self-contained
and often 200 to 500 MB, so ten old projects can hide several gigabytes. Find them
and their sizes:
find ~/www ~/Projects -name node_modules -type d -prune -exec du -sh {} + 2>/dev/null
Replace the example roots with the folders where you keep projects. -prune stops
find from descending into a matched dependency tree, and -exec handles spaces and
unusual characters in paths safely. A project can rebuild its dependencies only when
its source, lockfile, package manager version, registry access, and required native
toolchain are still available. Prefer the lockfile-specific command, such as npm ci,
after preserving those inputs.
Do not delete these
Package caches may be replaceable, but two neighbors are not. Project source and lockfiles
(package.json, package-lock.json, Cargo.lock) are not cache, they define the
build, so never sweep them. And a global store you are actively using, like a pnpm
content-addressed store shared across projects, will just re-download, but mid-install
deletion can corrupt it, so clear caches when nothing is building.
Under the hood: content-addressed stores, and why node_modules is the exception
Many package managers use content-addressed stores to reduce repeated downloads. pnpm
keeps one global store of every package version and hard-links them into each
project's node_modules, so ten projects using the same library share a single copy
on disk. Cargo and Go caches also key downloaded content by version or checksum. That
protects integrity, but it does not guarantee future availability. A conventional npm
install materializes a dependency tree per project, while pnpm can link projects to a
shared store. This is why deleting one node_modules directory and pruning a shared
store have different blast radii.
Use maps for discovery, package managers for cleanup
The scattered nature is the discovery problem. A treemap such as Mole's Analyze view can reveal which project or store is large, but the package manager's own verify, prune, or clean command understands its index and references. Use the map to choose a target and the owning tool to change it.
A safe order of operations
Stop builds and daemons, measure selected project roots, verify package-manager stores, and preserve source plus lockfiles before removing a dependency tree. Use documented prune commands rather than deleting an entire home-directory dot folder. Rebuild one project before emptying Trash. The purpose is to remove reproducible output while retaining the information needed to reproduce it.