How I reclaimed 27 GB on my 256 GB MacBook Air

Without losing any of my files

I got the "Your disk is almost full" energy the other day. Opened Disk Utility and saw 3.79 GB free on a 256 GB drive. Not great.

I didn't want to delete any actual projects or files. I just wanted to find all the invisible developer cruft that builds up over months of work — build caches, node_modules graveyards, toolchain artifacts, etc. I ended up reclaiming over 27 GB without losing anything I cared about.

Here's what I did, in the order I did it.

First — figure out where the space is going

Before deleting anything, I ran some reconnaissance:

1df -h / 2du -sh ~/Library/Developer/* 3du -sh ~/Library/Caches/* | sort -hr | head -20 4du -sh ~/Library/Application\ Support/* | sort -hr | head -15 5du -sh ~/Repos/* | sort -hr | head -20
bash

Adjust ~/Repos to wherever you keep your projects. The goal is just to see what's fat.

Xcode DerivedData

If you have Xcode installed, check this first:

du -sh ~/Library/Developer/Xcode/DerivedData

Mine was 3.5 GB. This is just build cache — Xcode regenerates it next time you build. Safe to nuke.

rm -rf ~/Library/Developer/Xcode/DerivedData

While you're at it, check for old iOS simulator runtimes. I had a 6.8 GB iOS 17.5 simulator just sitting there:

1xcrun simctl runtime list 2xcrun simctl delete unavailable 3xcrun simctl runtime delete <runtime-name-or-UUID>
bash

The node_modules graveyard

This is probably the biggest win for most JS/TS developers. Every project has a node_modules folder that can be 200 MB to over a gig. If you're not actively working on a project, there's no reason to keep it around. Just npm install when you pick the project back up.

Find all of them:

find ~/Repos -name "node_modules" -type d -maxdepth 4 | xargs du -sh 2>/dev/null | sort -hr

For a monorepo with nested node_modules everywhere, this is the nuclear option:

find ~/Repos/my-project -name "node_modules" -type d -prune -exec rm -rf {} +

I had about 6 GB of node_modules across repos I wasn't actively touching.

Next.js .next folders

If you use Next.js, the .next build cache can get big — especially in monorepos. Mine was 1.3 GB in one project.

1find ~/Repos -name ".next" -type d -maxdepth 5 | xargs du -sh 2>/dev/null | sort -hr 2find ~/Repos -name ".next" -type d -prune -exec rm -rf {} +
bash

Rust target directories

If you've ever run cargo build, the target folder is almost certainly massive. I had a Tauri project with a 3.1 GB target folder. This is compiled output — completely safe to delete, and cargo build regenerates everything.

rm -rf ~/Repos/my-rust-project/src-tauri/target

Application caches

macOS apps cache aggressively in ~/Library/Caches. These are all safe to delete — the apps rebuild them as needed.

du -sh ~/Library/Caches/* | sort -hr | head -20

I cleared out caches for Brave, Spotify, pnpm, bun, Cypress, Playwright, pypoetry, CocoaPods, node-gyp, and Homebrew. That was about 7 GB.

1rm -rf ~/Library/Caches/BraveSoftware 2rm -rf ~/Library/Caches/com.spotify.client 3rm -rf ~/Library/Caches/pnpm 4rm -rf ~/Library/Caches/bun 5rm -rf ~/Library/Caches/Cypress 6rm -rf ~/Library/Caches/ms-playwright 7rm -rf ~/Library/Caches/pypoetry 8rm -rf ~/Library/Caches/CocoaPods 9rm -rf ~/Library/Caches/node-gyp 10rm -rf ~/Library/Caches/Homebrew
bash

Also worth running:

1brew cleanup 2npm cache clean --force
bash

Electron app leftovers

Code editors and desktop apps built on Electron store a lot of data in ~/Library/Application Support/. If you've stopped using an editor or tool, its data sticks around.

du -sh ~/Library/Application\ Support/* | sort -hr | head -15

I had about 2 GB from editors I wasn't using anymore. Be careful here though — deleting Application Support data for active apps will reset your settings and sign you out.

Claude Code vm_bundles

This one caught me off guard. Claude's vm_bundles folder was 12 GB.

du -sh ~/Library/Application\ Support/Claude/*
1rm -rf ~/Library/Application\ Support/Claude/vm_bundles 2rm -rf ~/Library/Application\ Support/Claude/Cache 3rm -rf ~/Library/Application\ Support/Claude/Code\ Cache
bash

Claude re-downloads what it needs next time you use those features.

Docker

If you use Docker (I use Colima), check for unused images and containers:

1docker system df 2docker system prune -a
bash

Mine was clean, but this can easily be 5-10 GB if you've been pulling images over time.

What I left alone

  • /private/var/folders — This is macOS's temp directory. The OS manages it. Don't touch it.
  • Application Support for active apps — Deleting these resets settings. Not worth it.
  • Language toolchains (~/.cargo, ~/.rustup, ~/.bun) — I'm still using these, so I kept them. But if you're done with a language, uninstalling the toolchain can free up 1-2 GB.

Would a restart have fixed this?

No. Almost none of this gets cleaned up by restarting. A restart flushes some temp files and swap, but build artifacts, caches, node_modules, and toolchain data persist indefinitely. This kind of cleanup is manual.

The quick version

If you just want to run through this fast, here's a script. Read through it first and comment out anything that doesn't apply to you:

1#!/bin/bash 2 3# Xcode 4rm -rf ~/Library/Developer/Xcode/DerivedData 5 6# Node.js build artifacts (adjust path to your repos) 7find ~/Repos -name "node_modules" -type d -prune -exec rm -rf {} + 8find ~/Repos -name ".next" -type d -prune -exec rm -rf {} + 9 10# Rust build artifacts 11find ~/Repos -name "target" -type d -prune -exec rm -rf {} + 12 13# Package manager caches 14brew cleanup 2>/dev/null 15npm cache clean --force 2>/dev/null 16rm -rf ~/Library/Caches/pnpm 17rm -rf ~/Library/Caches/bun 18rm -rf ~/Library/Caches/Homebrew 19rm -rf ~/Library/Caches/CocoaPods 20rm -rf ~/Library/Caches/node-gyp 21rm -rf ~/Library/Caches/pypoetry 22 23# App caches 24rm -rf ~/Library/Caches/BraveSoftware 25rm -rf ~/Library/Caches/com.spotify.client 26rm -rf ~/Library/Caches/Cypress 27rm -rf ~/Library/Caches/ms-playwright 28 29# Claude Code 30rm -rf ~/Library/Application\ Support/Claude/vm_bundles 31rm -rf ~/Library/Application\ Support/Claude/Cache 32rm -rf ~/Library/Application\ Support/Claude/Code\ Cache 33 34# Docker (if applicable) 35docker system prune -a 2>/dev/null 36 37echo "Done! Check your free space with: df -h /"
bash

I went from 3.79 GB to 31 GB free. Not bad for an afternoon of rm -rf.