What it removes
Twenty-eight numbered sections, each one chosen from a menu or by number. Nothing runs that you did not select.
Xcode DerivedData and simulators, Gradle and Android caches, and the package-manager caches for npm, yarn, pnpm, Homebrew, pip, CocoaPods, cargo, go, Ruby and Flutter. All regenerate on next use.
~/Library/Caches and Saved Application State, /Library/Caches (sudo), and the cache directories of Chrome, Brave, Edge, Vivaldi, Chromium, Opera, DuckDuckGo, Arc and the Firefox family. Bookmarks, history and passwords are not touched.
Old user and system logs, $TMPDIR / /tmp / ~/tmp entries you own, and downloaded update caches. Trash is emptied only when you say so.
node_modules, vendor, dist, .next, target, Pods and similar directories inside your scan roots — but only when they have been untouched (atime AND mtime) for the full idle threshold.
Leftover application-support and container data with no installed app, and applications idle past your threshold. Apps go to the Trash, so they are recoverable until you empty it.
Several sections only look: system health, installer leftovers, large files, LaunchAgents audit and a disk-usage report write a dated .txt to ~/.mac-cleanup/reports/ and delete nothing.
How it avoids surprises
The guarantees below are real, and they are not a substitute for a backup. macleanup runs rm -rf and sudo on your machine, and you are responsible for verifying its output.
Every destructive helper checks the flag and prints what it would remove instead of removing it. Since 4.6.1 a dry run also estimates the space that would be freed.
Destructive operations prompt before running unless you pass --yes. Section 14 additionally requires a typed "yes" and a reboot afterwards.
Sections 6, 11, 14, 21 and 24 are refused in batch mode unless you add --i-understand-deep on top of --yes. --all (even --all --yes) never runs them.
In sections 12, 21, 23 and 24 an item is removed automatically only when it is both unused by any installed tool and untouched for at least --idle-days days.
A hard allowlist stops section 23 entering ~/.bun, ~/.pnpm-store, ~/.volta and friends, and it refuses to scan without explicit roots rather than falling back to your entire home directory.
The script makes no network calls. The single exception is the opt-in --check-update, an unauthenticated GET to the npm registry that sends no data about you.
Start here
Read what it deletes, preview a run, then install.