Developer cleanup

I Recovered 80GB by Cleaning Developer Toolchain Caches: The Breakdown

If you write code on a Mac, your disk is quietly being eaten alive. Package managers, build systems, compilers, and container runtimes all accumulate caches that were designed to make your next build faster — but over months and years they balloon into tens of gigabytes of data you almost never need again. The single fastest way to free up space on Mac as a developer is to audit and clear these toolchain caches systematically. This post documents exactly what was found during one such audit, the paths where it hides, and the commands to reclaim it safely.

Why Developer Caches Grow So Large

Every toolchain caches for a good reason. Rust caches compiled crates so you do not recompile serde for every project. npm caches tarballs so downloads are fast on fresh installs. Xcode caches compiled module maps, index stores, and build intermediates so incremental builds stay quick. The problem is that none of these tools have aggressive expiry policies. A cached version of a crate from 2022 will sit in ~/.cargo/registry/cache untouched for years. A DerivedData folder for a project you deleted six months ago still occupies gigabytes on disk because Xcode never cleaned it up.

On Apple Silicon Macs running macOS Sequoia or Tahoe, storage pressure is more acute because most developers chose the 512 GB base tier and headroom evaporates fast. Intel Macs with 256 GB SSDs are even more constrained. The audit below applies to both architectures.

The Full Breakdown: Where the 80 GB Came From

Here is a realistic breakdown of what a multi-language developer environment accumulates over roughly two years of active use. Sizes will vary by project mix, but the proportions are representative.

Toolchain / Cache Default Path Typical Size Safe to Delete?
Xcode DerivedData ~/Library/Developer/Xcode/DerivedData 15–30 GB Yes — next build regenerates it
Xcode Device Support ~/Library/Developer/Xcode/iOS DeviceSupport 5–20 GB Yes — old OS versions rarely needed
npm / pnpm cache ~/.npm / ~/.pnpm-store 2–8 GB Yes — re-downloaded on next install
Cargo registry & build cache ~/.cargo/registry, ~/.cargo/git 5–15 GB Yes — crates re-fetched as needed
Maven local repository ~/.m2/repository 2–10 GB Yes — Maven re-downloads on demand
Gradle caches ~/.gradle/caches 2–8 GB Yes — rebuild populates it again
Docker images & volumes Docker's virtual disk file 5–20 GB Prune unused; keep active images
Homebrew downloads cache ~/Library/Caches/Homebrew 1–4 GB Yes — brew cleanup handles it
CocoaPods cache ~/Library/Caches/CocoaPods 1–3 GB Yes — pods re-downloaded on install

For a deeper look at what the macOS storage system reports as "System Data" or "Other," see this breakdown of System Data on Mac storage — much of what developer caches generate ends up there.

How to Clear Xcode Caches Step by Step

Xcode is almost always the single largest contributor. Follow these steps to reclaim that space without breaking your development environment.

  1. Delete DerivedData. This is safe to remove entirely. Xcode recreates it on the next build.
    rm -rf ~/Library/Developer/Xcode/DerivedData
  2. Remove old iOS and watchOS device support files. These are large bundles Xcode downloads to debug on physical devices. You only need the version matching the iOS version your currently connected device runs.
    ls ~/Library/Developer/Xcode/iOS\ DeviceSupport/
    Delete folders for OS versions you no longer test on.
  3. Clear the Xcode Archives folder if it contains builds you no longer need to distribute.
    open ~/Library/Developer/Xcode/Archives
    Review in Finder before deleting — keep anything tied to an App Store submission you may need to re-export.
  4. Prune the module cache.
    rm -rf ~/Library/Developer/Xcode/DerivedData/ModuleCache.noindex
    This regenerates automatically when you next open a project.

For more context on why Xcode specifically hogs so much room, see why Xcode takes up so much space on Mac.

Clearing JavaScript and Node Caches

If you work with Node.js, the node_modules directories scattered across your project folders are often the biggest culprit — but the global package manager cache is the sneaky secondary offender.

npm cache

npm stores downloaded tarballs in ~/.npm. Run the built-in clean command:

npm cache clean --force

pnpm store

pnpm uses a content-addressable store at ~/.pnpm-store (or wherever pnpm store path reports). Prune unreferenced packages:

pnpm store prune

Yarn cache

yarn cache clean

Abandoned node_modules directories scattered across local repositories tend to be even larger than the global cache. Find them with:

find ~ -name "node_modules" -type d -prune -maxdepth 6 2>/dev/null

Delete the ones belonging to repositories you are no longer actively working on.

Rust and Cargo Registry Cleanup

Rust's package manager stores source code and compiled artifacts under ~/.cargo. The registry cache is safe to remove entirely; Cargo re-downloads crates on the next build that needs them.

du -sh ~/.cargo/registry
du -sh ~/.cargo/git

To remove just the downloaded source tarballs while keeping the index (faster to re-populate later):

rm -rf ~/.cargo/registry/src
rm -rf ~/.cargo/registry/cache

For a more surgical approach, the cargo-cache crate provides fine-grained reporting:

cargo install cargo-cache
cargo cache --autoclean

Project-level build artifacts live in each project's target/ directory and are typically even larger. Run cargo clean inside any project you are not actively building.

Java Ecosystem: Maven and Gradle

Maven

Maven stores every downloaded JAR, POM, and metadata file in ~/.m2/repository. There is no built-in prune command for stale artifacts, so the safest manual approach is to delete the entire repository. Maven re-populates it on the next project build.

du -sh ~/.m2/repository
rm -rf ~/.m2/repository

Gradle

Gradle caches build scripts, dependencies, and compiled daemon logs under ~/.gradle/caches. Gradle 8+ has a built-in cache cleanup that runs automatically after 30 days, but you can force it:

du -sh ~/.gradle/caches
rm -rf ~/.gradle/caches

You can also stop the Gradle daemon, which occasionally holds on to memory and writes to disk even when you are not building:

gradle --stop

Docker: Reclaiming Virtual Disk Space

Docker Desktop on macOS stores all images, containers, and volumes inside a single virtual disk image. That disk grows as you pull images but does not automatically shrink when you delete them. Use Docker's built-in prune commands to compact it.

# Remove stopped containers, dangling images, unused networks
docker system prune

# Also remove all unused images (more aggressive)
docker system prune -a

# Remove unused volumes separately
docker volume prune

After pruning, open Docker Desktop, go to Settings → Resources → Virtual Machine, and use "Reclaim disk space" to actually return the freed sectors to macOS.

Homebrew and Other Package Managers

Homebrew keeps old formula versions and downloaded bottles in ~/Library/Caches/Homebrew. The built-in cleanup command removes anything older than 120 days:

brew cleanup

To see what would be removed before actually doing it:

brew cleanup --dry-run

CocoaPods caches downloaded pod sources in ~/Library/Caches/CocoaPods. That directory is safe to delete — pods are re-fetched when you run pod install in any project.

rm -rf ~/Library/Caches/CocoaPods

Putting It All Together

Developer toolchain caches are among the least-visible but most impactful sources of disk consumption on a Mac. They accumulate silently because every individual tool made a reasonable decision to cache for speed — but no single tool has a view of the whole system. A tool like Crumb can audit all of these locations at once and show what is safe to remove before you delete anything, which is useful if you want to verify sizes without running a dozen du commands manually.

The high-level habit to build: run brew cleanup monthly, run cargo cache --autoclean after finishing a Rust project, and clear Xcode's DerivedData folder whenever your Mac starts warning about low storage. Together these four categories — Xcode, JavaScript, Rust, and Java — account for the majority of the recoverable space most developers are sitting on. A single focused cleanup session commonly returns 40–80 GB to active use without touching a single source file or installed application.

Reclaim your disk in one click

Crumb audits your whole Mac, tells you what's safe to delete, and frees the space in seconds — private, local, and Apple-notarized.

Download Crumb for macOS

Frequently asked questions

Is it safe to delete Xcode's DerivedData folder?
Yes, it is completely safe. DerivedData contains only build artifacts and index caches that Xcode regenerates the next time you open or build a project. You will not lose any source code or project settings.
Will clearing the Cargo registry delete my installed Rust toolchains?
No. The Cargo registry at ~/.cargo/registry holds downloaded crate source code and compiled artifacts. Clearing it does not affect your Rust toolchains, which are managed separately by rustup under ~/.rustup. Cargo will simply re-download any crates it needs on the next build.
How much space can a typical developer realistically recover?
It depends on how long you have been developing on the machine and which toolchains you use, but 20–80 GB is common for a Mac that has been in active development use for more than a year. Xcode DerivedData and Docker images tend to be the largest individual contributors.
Where does macOS report this space — under Applications, System Data, or Other?
Most developer caches appear under System Data or Other in the macOS storage breakdown in System Settings. That is because they live in hidden Library folders rather than in /Applications, so the OS does not attribute them to a specific application.
If I delete ~/.m2/repository, will my next Maven build fail?
No, Maven will simply re-download any missing artifacts from the remote repositories configured in your pom.xml (typically Maven Central). The first build after deletion will take longer than usual, but subsequent builds will be fast again once the local cache is repopulated.