Skip to content
cleandevmacPublic

About

Reclaim disk space on your Mac from developer caches, build artifacts, project junk and leftover app data. One curl, no install, nothing deleted without confirmation.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

CleanDevMac

English | العربية | Español | 日本語 | 简体中文 | 繁體中文

Downloads Latest release Stars License Platform Donate

CleanDevMac — cdm on your command line — is a terminal UI that finds the dev caches, build artifacts and leftover app data eating your disk, shows you exactly what and how big, and deletes only what you tick.

The downloads badge counts fetches of the cdm release asset. Every curl install below hits that asset, so it is the real usage counter for this tool.

Site: https://cleandevmac.github.io

macOS only. Pure bash, no dependencies. Zero telemetry — the only network call cdm ever makes is fetching its own rule JSON. (Pressing b after a clean opens the donate link in your browser; nothing is ever sent anywhere.)

Run it

curl -sSL https://github.com/cleandevmac/cdm/releases/latest/download/cdm | bash

There is no install step. The script runs straight from the pipe, scans, and hands you the TUI. When it exits, nothing of it is left on your Mac.

Dry run first — scans and reports, deletes nothing:

curl -sSL https://github.com/cleandevmac/cdm/releases/latest/download/cdm | bash -s -- -n

Keep it around (optional)

Only do this if you want to run cdm again without the URL. It is the one thing here that does leave a file behind:

mkdir -p ~/.local/bin
curl -sSL https://github.com/cleandevmac/cdm/releases/latest/download/cdm -o ~/.local/bin/cdm
chmod +x ~/.local/bin/cdm
cdm

Make sure ~/.local/bin is on your PATH (export PATH="$HOME/.local/bin:$PATH" in your shell rc). Re-run the curl -o line to update. To uninstall: rm ~/.local/bin/cdm.

CleanDevMac

What it cleans

1. Dev caches & build artifacts — Xcode DerivedData and DeviceSupport, Go build & module cache, npm/npx/pnpm/yarn, JS build tools (Turbo, Vite, webpack, Parcel, ESLint), Gradle, Maven, sbt/Ivy, Cargo, Python (pip, uv, poetry, ruff, mypy), Ruby/Bundler, Bun, Deno, CocoaPods, SwiftPM, Composer, Bazel, Zig, cloud CLIs (kubectl, AWS, gcloud, Azure, wrangler), Docker buildx, JetBrains, Zed's downloaded language servers, Playwright, the Homebrew and PlatformIO download caches, Android Studio caches and emulator snapshots, Android system images no AVD uses any more, and — in your own temp folders under /private/var/folders — clang's module cache and Node's compile cache.

2. Installed SDK pieces that download again — all opt-in, each row saying how it comes back: PlatformIO's installed platforms and toolchains (the next pio run fetches what it needs); the Android NDK, CMake and SDK sources; every Android build-tools and platform version but the newest; the system image of an AVD nobody has started in 60 days (the row names the AVD, which will not boot until the image is reinstalled); every Rust toolchain other than your default and stable, removed with rustup toolchain uninstall (the row names any repo that pins it); and each toolchain's offline docs (rust-docs, ~0.9 GB apiece), removed with rustup component remove rust-docs. sdkmanager, adb, the emulator and PlatformIO's own pio are never offered.

3. Old Claude Code transcripts — opt-in: sessions untouched for 30 days, with their subagent and tool-output files, go to the Trash. Running sessions, auto memory and settings are never touched. When the history is large, cdm also prints the ~/.claude/settings.json key (desktopSessionCleanupPeriodDays) that makes Claude Code age out its Desktop and Cowork sessions itself — it never edits that file.

4. Electron, browser & app caches — VS Code (including the agent SDK it downloads), Claude (including per-preview webview caches and, opt-in, the Cowork VM image and the Claude Code builds older than the one it runs), Slack, EasyEDA; Chrome, Brave, Edge, Vivaldi and Arc scanned per browser profile; Firefox; the copy of itself Chrome makes at each launch, which a crashed or killed browser (say, under a test script) leaves behind — never one a running browser may use; installed-update leftovers; crash/telemetry SDK caches (Sentry, Crashlytics, Sparkle); and, opt-in, Chrome's on-device AI models and the aerial wallpaper videos macOS downloads into every account.

5. Project junk, grouped per repo — node_modules, dist, build, target, __pycache__, and git-ignored files. Only ever what the repo itself git-ignores. Off by default; pass -p to enable it. Interactive runs offer it after the cache scan finishes.

6. Docker / Podman — system prune -af, plus buildx prune -af on each buildx builder's cache (a stopped builder is started for it and stopped again), opt-in. Named volumes are never deleted.

7. Orphaned app data — Application Support, Caches and Preferences belonging to apps that are no longer installed, plus the folders some apps keep under their own name — VS Code's ~/.vscode and Application Support/Code, Cursor, Zed, Docker Desktop, Postman, Slack, JetBrains IDEs, Android Studio and about 30 more listed in orphans.json. Folders a command-line tool also uses (~/.docker, ~/.ollama, ~/.codex, ~/.android, ~/.cursor) and Docker Desktop's VM disk get a separate (optional) row that says when to leave them, and a shared folder is never offered while a command that uses it (docker, ollama, codex, adb, …) is still on your PATH.

What a restart would free. Swap, the temp folders macOS empties at boot, and files deleted while an app still holds them open are not files any cleaner can delete — yet on a full disk they can add up to tens of GB. When they come to more than the disk has free, cdm says so under the disk line, and again in the menu, and names the apps holding deleted files: quitting those frees that part without a restart.

Safety

  • Nothing is deleted without an itemized confirmation. You see the plan and the sizes, then type y.
  • Caches are deleted permanently — they regenerate on the next build.
  • Orphaned app data, git-ignored files and old Claude Code transcripts go to the Trash, so they are recoverable.
  • Anything that removes installed software starts unchecked — SDK pieces, toolchains, emulator images — and its row says how it comes back. Rust toolchains and their offline docs are removed by rustup, never by rm.
  • Outside your home folder, cdm reaches only your own temp and cache folders — the /private/var/folders ones macOS keeps for your account — and only the folders a rule names inside them. Not the folders themselves, nor anyone else's.
  • Never touched regardless of what the rules say: ~/Documents, ~/Desktop, ~/Downloads, ~/Pictures, ~/.ssh, and iCloud Drive. This guard sits below the rule engine — a rule cannot opt out of it.
  • A folder is only project junk if your repo git-ignores it. Matching a name like dist, build or Pods is not enough — cdm verifies with git that the directory is ignored and untracked, so a tracked build/ of release scripts or a committed dist/ is left alone.
  • .env* files are never offered for deletion. The project scan skips them even though they're git-ignored — they hold secrets and local config nothing regenerates.
  • App sandboxes and Apple/system-owned data are never touched. The one exception is an uninstalled Docker Desktop's container, which holds its VM disk; it is offered only in an unchecked (optional) row.
  • The installed-app list is read from LaunchServices, so prefPanes, plugins and other non-.app bundles aren't mis-flagged as orphaned. An app sitting in the Trash, or one LaunchServices reports as gone, counts as uninstalled.
  • --dry-run deletes nothing.
  • Every run is logged to ~/.cleandevmac/clean.log.

TUI keys

cdm shows your disk — total, used, free — before it scans, the most it could reclaim once the scan finishes, and what the disk looks like again after a clean.

Key Action
↑ / ↓, k / j Move
Space Toggle the selected item
a / s / n Select all / safe defaults / none
Enter (or d) Show the exact paths and sizes behind an item
c Clean — builds an itemized plan, confirm with y
q (or Esc) Quit

After a clean it prints the receipt and asks what next: r rescan · b buy me a coffee · q quit (the default — Enter or any other key does the same).

Items are sorted biggest-first. Safe regenerable caches are pre-selected; the Maven repository, Playwright browsers, crash logs, installed SDK pieces, old Claude Code transcripts, project folders and orphaned app data all start unchecked — s resets to that default selection.

Editable rules

Targets live in JSON under rules/, not in code. Add or remove paths by editing these files:

File Contents
index.json Manifest — which rule files load, and in what order
dev-caches.json Dev caches & build artifacts
app-caches.json Electron, browser & app caches
containers.json Docker / Podman
project-junk.json Per-repo project junk
orphans.json Orphaned app data detection

Each category is an object with icon, name, desc, paths, default (pre-selected or not) and method (rm to delete, trash to move to the Trash). Point cdm at your own set with --patterns <dir-or-url>.

A category may also carry procs — the process names of apps that would rewrite those caches while running ("procs": ["Google Chrome", "Code"]). cdm names any that are open before asking you to confirm, since clearing a cache under its own app just hands the space straight back. Names must match pgrep -x exactly.

A few categories set a kind, and the script works out what they offer: android-images (system images no AVD boots), android-idle-images (images only AVDs idle for idleDays boot), older-versions (each glob is a family of versions; all but the newest), rust-toolchains (toolchains other than the default and stable) and claude-transcripts (sessions untouched for idleDays, always to the Trash). They take their globs from images or candidates, never paths, so a cdm too old to know the kind offers nothing.

Options

Option Effect
-n, --dry-run Scan and report; delete nothing
-y, --yes Non-interactive: clean the pre-selected safe caches, then exit. Never touches project folders, orphaned app data, or the Trash
-p, --projects Also scan code repos for project junk
--patterns SRC Load rules from a local directory or a base URL
--no-color Disable ANSI color
-h, --help Usage

Environment

Variable Effect
CDM_REMOTE Base URL rules are fetched from when no local copy is found
CDM_PATTERNS Rule source — a local directory or a base URL (same as --patterns)

Support

cdm is free and MIT, and it stays that way — no paid tier, no telemetry, nothing held back. If it gave you your disk back and you feel like buying me a coffee:

paypal.me/hoangnc

Starring the repo or telling another developer about it helps just as much.

Credits

Some cache locations were cross-checked against other open-source macOS cleaners:

The rules here are written independently for this tool's own schema, and each path was verified before being added.

License

MIT — see LICENSE.

About

Reclaim disk space on your Mac from developer caches, build artifacts, project junk and leftover app data. One curl, no install, nothing deleted without confirmation.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Contributors

Languages