Documentation
Dustpan 0.1.0. Keyboard: ⌘R rescan, ⌘, settings, Esc closes dialogs.
Install
- Open
Dustpan_0.1.0_aarch64.dmgand drag Dustpan to Applications. - Open Dustpan from Applications.
Builds that aren't signed and notarized are blocked by macOS the first time. If that happens, Control-click Dustpan in Applications, choose Open, then Open again. The current build is for Apple silicon Macs running macOS 11 or later.
First scan
On first launch Dustpan asks where you keep your code. Your home folder is included by default. Add other folders, such as an external drive with projects, with Add folder…. Global caches, Xcode data and simulators are always checked, wherever your projects are.
While searching your home folder, Dustpan skips places that never hold projects or that sync with the cloud:
~/Library (except the known cache locations), Applications, Music, Movies, Pictures, Dropbox,
OneDrive, Google Drive and hidden folders.
macOS may ask to let Dustpan access Documents, Desktop, Downloads or a removable drive. Allow it if you keep projects there. If you decline, Dustpan skips those folders and shows how many couldn't be read. You can change your answer later in System Settings › Privacy & Security › Files and Folders.
Scanning reads folder names, file sizes and dates, plus a few tool metadata files (Xcode's DerivedData
info.plist, Android emulator .ini files). It never changes anything. Cancelling a scan
keeps your previous results.
Reading the list
Items are grouped into Projects, Caches and Simulators & emulators, and sorted largest first. Each row shows:
- Name: the project folder, cache or device, with the leftover folder's name.
- Size: space used on disk. Files hard-linked from elsewhere, like a pnpm store, are counted once per item, and the details say when less space may be freed.
- Last used: for projects, the most recent of your last install or build in that folder, your last git activity, and changes at the top of the project. For caches, the newest file inside. For simulators, the last boot Xcode recorded. Orphaned means it can't be used any more: a simulator whose runtime was removed, or DerivedData for a project that no longer exists.
- Safety level:
| Level | Meaning | Pre-selected? |
|---|---|---|
| Safe | Your tools download or recreate it automatically. | If unused for your chosen time, or orphaned |
| Rebuild | Comes back when you run install or build again. The details show the command. | If unused for your chosen time |
| Review | May hold things you can't get back, or is expensive to restore: simulator and emulator data, Xcode archives, Android system images, simulator runtimes, the Maven repository, JetBrains caches, and generic folders like build that git doesn't confirm are ignored. | Never |
Click a row for its full path, restore instructions and notes, and to show it in Finder. Running simulators and emulators are marked In use and can't be selected.
Suggest items unused for sets the cut-off for pre-selection (default 30 days). Changing it replaces the current selection with the new suggestions.
Cleaning up
Select items and choose Clean up…. The confirm dialog breaks the selection down by safety level and lists the commands you'll need to rebuild. If you selected anything marked Review, you have to confirm you've checked it.
- Move to Trash (default): reversible. The space is freed when you empty the Trash. Items on an external drive go to that drive's Trash.
- Delete permanently: frees space immediately and can't be undone. Read-only folders, like Go's module cache, are handled.
- iOS simulators and runtimes are always deleted with Xcode's
xcrun simctl. They can't go to the Trash.
Right before removing each item, Dustpan checks again that it still exists, isn't a symbolic link, still sits in
a scanned folder, and still matches its rule (for example, the package.json next to
node_modules is still there). Items that fail the check are skipped and reported. Stop
finishes the current item and leaves the rest.
Hiding items
Open an item and choose Never suggest this to hide it from future scans. Hidden items are listed in Settings, where you can show them again.
Settings
Folders to search, hidden items, optional encrypted backup and optional anonymous stats. Settings are saved as soon as you change them. The suggestion cut-off sits above the results, and the confirm dialog remembers whether you last chose the Trash or Delete permanently.
What Dustpan checks
Project folders
A folder counts only when the marker file is in the same project.
| Folder | Needs | What it is |
|---|---|---|
node_modules | package.json | Node.js dependencies |
target | Cargo.toml / pom.xml | Rust / Maven build output |
.venv, venv, env | pyvenv.cfg inside | Python virtual environment |
.tox, .nox | tox.ini, noxfile.py, pyproject.toml or setup.py | Python test environments |
.next, .nuxt, .svelte-kit, .turbo, .parcel-cache, .docusaurus | package.json | JavaScript framework caches |
.angular | angular.json | Angular build cache |
Pods | Podfile | CocoaPods dependencies |
.build | Package.swift | Swift Package Manager build output |
.gradle, build* | build.gradle(.kts) / settings.gradle(.kts) | Gradle cache and build output |
build*, .dart_tool | pubspec.yaml | Flutter / Dart |
bin*, obj* | *.csproj, *.fsproj, *.vbproj | .NET build output |
_build, deps* | mix.exs | Elixir |
.stack-work / dist-newstyle | stack.yaml / cabal.project or *.cabal | Haskell |
.zig-cache, zig-cache, zig-out | build.zig | Zig |
.terraform | *.tf | Terraform providers and modules |
vendor* | composer.json | PHP Composer dependencies |
elm-stuff | elm.json | Elm |
cmake-build-* | CMakeLists.txt | CLion CMake build folders |
* Generic names. They're marked Review unless git confirms they're ignored, including in projects that aren't git repositories. Pods inside a git repository must be git-ignored too.
Caches and tool data (macOS paths)
| Item | Location | Level |
|---|---|---|
| Xcode DerivedData (per project) | ~/Library/Developer/Xcode/DerivedData/* | Safe |
| Xcode device support (per OS version) | ~/Library/Developer/Xcode/iOS DeviceSupport/* (and watchOS, tvOS, visionOS) | Safe |
| Xcode archives | ~/Library/Developer/Xcode/Archives/* | Review |
| Simulator caches, test device clones | ~/Library/Developer/CoreSimulator/Caches, ~/Library/Developer/XCTestDevices | Safe |
| npm, Yarn, pnpm, Bun | ~/.npm/_cacache, ~/Library/Caches/Yarn, ~/.yarn/berry/cache, ~/Library/pnpm/store, ~/.bun/install/cache | Safe |
| pip, uv, Poetry | ~/Library/Caches/pip, ~/.cache/uv, ~/Library/Caches/pypoetry | Safe |
| Cargo | ~/.cargo/registry/cache, …/registry/src, ~/.cargo/git/checkouts, …/git/db | Safe |
| Go | ~/Library/Caches/go-build, $GOPATH/pkg/mod (default ~/go) | Safe |
| Gradle | ~/.gradle/caches, ~/.gradle/wrapper/dists/* | Safe |
| Maven | ~/.m2/repository | Review (may hold artifacts you built with mvn install) |
| CocoaPods, SwiftPM, Homebrew | ~/Library/Caches/CocoaPods, …/org.swift.swiftpm, …/Homebrew | Safe |
| Playwright, Puppeteer, Electron | ~/Library/Caches/ms-playwright/*, ~/.cache/puppeteer, ~/Library/Caches/electron | Safe |
| Composer, NuGet, pub, Deno | ~/Library/Caches/composer, ~/.nuget/packages, ~/.pub-cache/hosted, ~/Library/Caches/deno/{deps,npm,gen,remote} (not Deno KV / localStorage data) | Safe |
| JetBrains IDE caches | ~/Library/Caches/JetBrains/* | Review (also holds the IDE's Local History) |
| Android system images | $ANDROID_HOME/system-images/* (default ~/Library/Android/sdk) | Review |
On Linux, ~/Library/Caches becomes ~/.cache.
Simulators and emulators
- iOS simulators, from
xcrun simctl list devices. Ones whose runtime is no longer installed at all are Safe and marked orphaned; all others, including temporarily unavailable ones, are Review because they hold installed apps and data. - Simulator runtimes, from
xcrun simctl runtime list, if they can be deleted. Review; they take several GB to download again. - Android emulators, from
~/.android/avd(or$ANDROID_AVD_HOME). Review.
Dustpan only calls xcrun if simulators have been used on the Mac, so it never triggers
the developer tools install prompt.
Command line
The dustpan CLI uses the same engine and the folders you chose in the app (or your home folder).
dustpan scan [FOLDER…] [--json] [--older-than DAYS] dustpan clean [FOLDER…] [--older-than DAYS] [--kind KIND]… [--permanent] [--dry-run] [--yes]
scanlists everything, marking suggestions with*and in-use items with!. It changes nothing.cleanremoves suggested items only: Safe or Rebuild, not in use, and unused for--older-thandays (default 30) or orphaned. Items marked Review are never removed by the CLI.--kindlimits cleaning to rule ids likenode_modules,cargo-target,npmorxcode-derived-data(the ids appear inscanoutput).--dry-runprints the plan and stops. Without--yes,cleanasks for confirmation and refuses to run when there's no terminal to ask in.- Items go to the Trash unless you pass
--permanent. Simulators are always deleted withsimctl. - If the settings file is damaged,
cleanrefuses to run (it holds your hidden-items list);scanwarns and uses defaults. - Exit code 1 means some items couldn't be removed; 2 means confirmation was required.
Troubleshooting
"N folders couldn't be read"
macOS blocked access, usually because a folder permission request was declined. Click Show to see which folders, then allow Dustpan in System Settings › Privacy & Security › Files and Folders (or Full Disk Access) and rescan.
"Folder not found — is the drive connected?"
A scan folder is on a drive that isn't mounted. Connect it and rescan, or remove it in Settings.
An item couldn't be removed
The report says why. Common reasons: another app is using it (quit the IDE or emulator), it changed since the scan (rescan), or it's a simulator that's booted (shut it down).
My disk space didn't change
Items were moved to the Trash. Empty the Trash, or choose Delete permanently next time.
A project I use every day was suggested
Its last activity is older than your cut-off: no install, build or git activity, and nothing changed at the top of the project. Raise the cut-off, or use Never suggest this.
Uninstall & data
Dustpan stores two files: settings.json and last_scan.json (the last results, so the
list appears instantly next time). On macOS they're in ~/Library/Application Support/Dustpan/; on
Linux in ~/.config/Dustpan/. To uninstall, quit Dustpan, move it from Applications to the Trash, and
delete that folder.
Build from source
# requires Rust 1.85+ and Node 20+ cargo test # core + CLI tests cargo build --release -p dustpan # CLI → target/release/dustpan cd app && npm install npx playwright test # UI tests (demo backend) npx tauri build # app → target/release/bundle/