Allowlist only
A path is deletable only if it descends from an explicit target in the registry. There is no "delete everything except" logic anywhere in the codebase. The rules are data you can read.
Dusty lives in your menu bar and reclaims the gigabytes hiding in caches, logs, and developer junk. It can only ever delete from a fixed allowlist, and it shows you every path and its size before it removes a thing.
$ brew install --cask yagcioglutoprak/tap/dusty
Most "Mac cleaners" are closed software that deletes files you cannot see. Dusty is the opposite. The deletion logic is a separate, unit-tested Swift package, and a single validator is the only thing that can authorize a delete. These are the rules it enforces.
A path is deletable only if it descends from an explicit target in the registry. There is no "delete everything except" logic anywhere in the codebase. The rules are data you can read.
Documents, Desktop, Photos, Mail, iCloud Drive, and Keychains are rejected even as path prefixes.
Symlinks are never followed, so a delete can never walk out of an allowed directory.
Confined to the volume your home folder lives on. Never runs as root, never uses sudo.
Flip one toggle to scan and report exact bytes, without removing a thing.
Developer and Deep cleanups can land in the Trash, with an undo window right after. Nothing is irreversible by surprise.
Every action, with timestamp, path, and exact bytes, is appended to a plain JSON log in Application Support you can open any time. Nothing happens off the books.
Level 01
User caches, app logs, the Trash, and browser caches. The everyday stuff that piles up on its own.
Regenerates on its own. Zero functional impact.
Level 02
Xcode DerivedData and simulators, plus caches for npm, pnpm, pip, Cargo, Go, Homebrew, Gradle, CocoaPods, SwiftPM, JetBrains, and Unity.
Rebuilds or re-downloads next time you need it.
Level 03
Old .dmg and .pkg installers in Downloads, Xcode archives, unused simulators, and aged diagnostic logs.
Per-file checklist. Nothing goes without a tick.
Some paths ask for Full Disk Access| Dusty | CleanMyMac and similar | |
|---|---|---|
| Price | Free, MIT licensed | Paid license or subscription |
| Source code | Open, every rule is readable | Closed |
| What it can delete | A fixed allowlist, nothing else | Broad categories, not all visible |
| Sizes shown before deleting | ✓ Always, per path | Varies |
| Undo and a deletion log | ✓ Yes | Varies |
| Account or telemetry | None | Often |
Adding a cache is a single entry that the scanner, the UI, and the safety checks all pick up. That is the whole contribution model, so pull requests are easy.
CleanupTarget( id: "dart-pub-cache", displayName: "Dart and Flutter pub cache", level: .developer, pathTemplates: ["~/.pub-cache"], category: "Package Manager", deletesContentsNotDirectory: true, regenerates: true ) // one entry, everywhere it needs to be
Free, open source, signed and notarized. Installs in one line.
$ brew install --cask yagcioglutoprak/tap/dusty