Skip to content

A cleanup script for developers that shows first and moves to the Trash

One script that sizes every regenerable developer cache on a Mac, prints a report, and only moves things to the Trash when you ask. Every path explained.

7 min read

Cleanup scripts found online usually do the dangerous thing: rm -rf on a long list of paths, run blind. This one does the opposite. By default it only measures and prints. With --trash it moves each folder to the Trash, so any mistake is one drag away from being undone.

The script

#!/usr/bin/env bash
# dev-clean.sh: size developer caches; with --trash, move them to the Trash.
set -u
MODE=${1:-report}
PATHS=(
  "$HOME/.npm/_cacache"
  "$HOME/.npm/_npx"
  "$HOME/Library/Caches/Yarn"
  "$HOME/.yarn/berry/cache"
  "$HOME/Library/pnpm/store"
  "$HOME/Library/Caches/pnpm"
  "$HOME/.bun/install/cache"
  "$HOME/Library/Caches/node-gyp"
  "$HOME/.cache/node/corepack"
  "$HOME/Library/Caches/ms-playwright"
  "$HOME/.gradle/caches"
  "$HOME/.cargo/registry/cache"
  "$HOME/Library/Caches/pip"
  "$HOME/.cache/uv"
  "$HOME/Library/Caches/Homebrew"
  "$HOME/Library/Developer/Xcode/DerivedData"
  "$HOME/Library/Caches/CocoaPods"
  "$HOME/.expo"
)
total=0
for p in "${PATHS[@]}"; do
  [ -e "$p" ] || continue
  kb=$(du -sk "$p" 2>/dev/null | cut -f1)
  total=$((total + kb))
  printf '%8.1f MB  %s\n' "$(echo "$kb/1024" | bc -l)" "$p"
  if [ "$MODE" = "--trash" ]; then
    mv "$p" "$HOME/.Trash/$(basename "$p")-$(date +%s)"
  fi
done
printf '\n%8.1f GB  total\n' "$(echo "$total/1048576" | bc -l)"
if [ "$MODE" = "--trash" ]; then
  echo "Moved to the Trash. Empty it to free the space."
fi

Using it

chmod +x dev-clean.sh
./dev-clean.sh           # report only
./dev-clean.sh --trash   # move to the Trash

What is on the list, and why

Only folders that the owning tool recreates by downloading or building again. Nothing that holds your work, settings or credentials:

PathRebuilt byGuide
~/.npm/_cacache, ~/.npm/_npxnpm, npxnpx cache
Yarn, pnpm, Bun storesthe next installYarn and pnpm
node-gyp, Corepacknative buildsnative module caches
Playwright browsersnpx playwright installPlaywright
Gradle and Cargo cachesthe next buildGradle
pip and uv cachesthe next installuv
Homebrew downloadsbrew installHomebrew cache
DerivedData, CocoaPodsthe next Xcode buildDerivedData

What is deliberately not on it

  • Runtime versions (nvm, rustup, JDKs): removing the one you use breaks your setup. Remove old ones by name.
  • node_modules in projects: safe, but better done per project, since an active project will need a full reinstall.
  • AI tool sessions and databases: they are history and data, not cache.
  • Docker: use docker system prune, which knows what is in use.

Moving to the Trash means the space only returns once you empty it, which is the point: you can check nothing broke first. A monthly habit around it is in a monthly Mac cleanup routine, and one-line commands for the rest in terminal commands to free space.

Related: Developer in Mac storage.

Related: CMake build folders and ccache and vcpkg build trees.

Common questions

Is there a safe script to clear developer caches on a Mac?

Yes. The script in this guide reports sizes by default and, with --trash, moves each cache to the Trash instead of deleting it.

Which developer folders are safe to delete on a Mac?

Package caches, build caches and downloaded browsers or headers: npm, Yarn, pnpm, Gradle, Cargo registry, pip, uv, Homebrew downloads and Xcode DerivedData.

Why move caches to the Trash instead of rm -rf?

So a mistake can be undone. The space returns when you empty the Trash, after you have checked your tools still work.

Should a cleanup script delete node_modules?

Better not automatically. It is safe, but an active project then needs a full reinstall, so it is better done per project.

Read next