Mac Storage Dashboard
A local, privacy-friendly dashboard that maps your whole Mac's disk, classifies reclaimable space into safe to remove vs review first, and lets you clean up with full control — either by copying a reviewed script, or with explicit, confirmed deletion right in the app.
Quick start
Option A — Homebrew cask (recommended). Puts the app straight into /Applications:
brew install --cask irfanwani/tap/mac-storage-dashboard
First launch needs your approval — the app isn't notarized by Apple yet, so macOS says it "cannot verify" it. Allow it either via System Settings → Privacy & Security → Open Anyway, or in one line:
xattr -dr com.apple.quarantine "/Applications/Mac Storage Dashboard.app"Re-apply after every
brew upgrade— Homebrew quarantines each new download. Want zero approval prompts instead? Option B builds the app locally, which macOS never quarantines.
Option B — PyPI (pipx). The package builds the app for you and installs it into
/Applications (falls back to ~/Applications):
brew install pipx # if you don't have it yet
pipx install mac-storage-dashboard
mac-storage-dashboard install
Option C — from source. Clone the repo and build the app:
./build_app.command # creates dist/Mac Storage Dashboard.app (app icon == favicon)
Either way you end up with Mac Storage Dashboard as a normal macOS app. It's
self-contained: move it anywhere, including /Applications. Double-click it — it
starts the dashboard server in the background and opens it in your browser, and macOS
asks that app for disk access instead of your terminal. Want it off? Click ⏻ Stop
in the dashboard.
(Releases are automated — bump __version__, merge to main, and
the release workflow tags, builds, publishes to
PyPI and updates the Homebrew tap. First-time setup: RELEASING.md.)
Terminal alternative: mac-storage-dashboard run (or, from a clone,
python3 mac_storage_dashboard/server.py) starts the same server and opens
http://127.0.0.1:8899. Double-clicking run.command does the same.
Requires macOS and Python 3.9+ (any stock Mac has it, or run xcode-select --install).
The first scan takes about a minute (~1M files). Nothing leaves your Mac: the server
binds to 127.0.0.1 only.
Features
- Explorer — treemap of your home folder sized by real disk usage. Click a tile to zoom, ⌘-click (or double-click) to reveal it in Finder. The Cleanup tab filters to reclaimable space only (green = safe, yellow = review first).
- Recommendations — tick items to build a cleanup script (
Copy/Download), or hit Delete selected to remove them in-app after a confirmation step. - Insights — what's wasting space and the single command that fixes each thing.
- Rescan — re-maps the disk and refreshes every number.
Permissions (Full Disk Access) — read this once
macOS protects folders like Desktop, Documents, Mail, Messages, Safari, Photos and iPhone backups via privacy protection (TCC). Whatever app launches the scanner — Terminal, iTerm, VS Code, or the bundled Mac Storage Dashboard app — needs Full Disk Access, or those folders are invisible (their sizes show up as 0 / missing).
Why not the browser? Your browser can't scan your disk, and granting it Full Disk Access wouldn't help — the browser is only the window. A small local scanner does the reading, and macOS attributes the permission to the app that launched it. That's exactly why the bundled app exists: grant access to Mac Storage Dashboard once and no Terminal is involved.
This is also why tools built on du are quietly broken on modern macOS: du returns
0 for protected folders without telling you. This dashboard instead:
- scans with a pure-Python walker (real sizes, one pass over ~1M files),
- detects protected folders it can't read and tells you exactly which ones,
- shows a banner naming the exact app to grant (the app or your terminal) plus steps.
Grant it in 30 seconds
- Click Open Privacy Settings in the dashboard banner (or open System Settings → Privacy & Security → Full Disk Access).
- Enable the app the banner names — Mac Storage Dashboard if you launched the app, otherwise your terminal app. Add it with + if it's missing.
- Reopen that app (the permission applies on restart).
- Run a Rescan.
No banner? The scan already has full access — nothing to do.
From the terminal you can check readiness at any time:
python3 mac_storage_dashboard/scanner.py --check
…which prints which protected folders are readable, the app macOS will attribute the
scan to, and your disk usage. Exit code is 0 when everything is readable.
Deleting space (how the app keeps it safe)
There are two ways to free space, and both are deliberate:
-
Copy script — the dashboard generates
rmcommands for the items you ticked; nothing runs until you paste and execute it. -
Delete selected — the in-app path. The server deletes only the exact paths the scanner found for the items you ticked. Guard rails:
- the API accepts item IDs only, never arbitrary paths, and re-validates every
path against the current
data.jsonbefore touching anything; - a hard-coded protection list refuses
/, your home folder,/Library,/System,/usr,/Applicationsand friends; - items that need
sudo(system caches, simulator runtimes…) are skipped in-app and flagged "use the script" instead — the dashboard never asks for your password; - deletion requires an explicit confirmation with an "I understand" checkbox;
- deleted items are permanently removed (not moved to Trash) — that's the point of freeing disk space; the confirmation dialog says so in plain words;
- after deleting, the dashboard updates instantly — the server subtracts exactly what was removed from the sizes, totals, treemaps and insights (no full rescan; a rescan only happens if that in-place update isn't possible).
- the API accepts item IDs only, never arbitrary paths, and re-validates every
path against the current
When in doubt, start with the green safe tier — those are caches that regenerate
by themselves (npm/Homebrew/pip caches, Xcode DerivedData, simulator caches…). Yellow
review items are real data (iOS backups, node_modules, VM images, old downloads).
What it finds
| Where | Examples |
|---|---|
| Package caches | npm, yarn, pnpm, pip, uv, Homebrew, Go, Maven, Gradle, CocoaPods, SwiftPM |
| Xcode | DerivedData, DeviceSupport, simulator caches, archives, simulators |
| System | simulator runtime caches, /Library/Updates, /Library/Caches, system assets (Siri voices, offline models) |
| Projects | node_modules, .next/.turbo/venv build output, __pycache__ |
| User | Trash, old Downloads (installers), iOS backups, VMs, Ollama models, Docker |
| Android | SDK, AVD emulator images |
CLI
Installed via pipx/PyPI:
mac-storage-dashboard run # start the dashboard (opens in your browser)
mac-storage-dashboard app # build "dist/Mac Storage Dashboard.app"
mac-storage-dashboard install # build + copy the app into /Applications
mac-storage-dashboard doctor # permission doctor (Full Disk Access readiness)
mac-storage-dashboard uninstall # remove the app (--purge-data also erases scans)
From a clone (no install needed):
python3 mac_storage_dashboard/scanner.py # scan only → data.json
python3 mac_storage_dashboard/scanner.py --check # permission doctor
python3 mac_storage_dashboard/server.py # dashboard + APIs on :8899
python3 mac_storage_dashboard/server.py 9000 # …on a custom port
Privacy & security
- Everything runs locally; there is no telemetry, no network calls, no cloud.
- The server binds to
127.0.0.1, checks theHost/Originheaders on every request, and refuses anything that isn'tlocalhost. - Scan results stay on your Mac in
data.json— app/CLI installs keep it in~/Library/Application Support/Mac Storage Dashboard/; running the scripts from a clone writes it next to the code. Delete the wholedata.jsonto erase scan results (the dashboard can regenerate it with a rescan). data.json,scan_state.jsonandscan_log.txtare generated files and are.gitignored; the repo contains code only.
Accuracy notes
- Sizes are allocated disk blocks (
st_blocks × 512) — whatdfreports — with hard-link deduplication. Decimal units (1 GB = 1,000,000,000 bytes). - The walker skips nothing it can read: caches, node_modules, system folders, other user-visible data outside your home are all included, so the numbers add up.
- Without Full Disk Access some folders are skipped — the dashboard shows you which ones instead of silently under-reporting.
Files
mac_storage_dashboard/ the Python package
scanner.py single-pass disk walker → data.json (sizes, junk tiers, insights, permissions)
server.py localhost server (dashboard + rescan/cleanup/shutdown APIs)
index.html the dashboard UI (zero dependencies, works offline)
favicon.svg tab icon (nested treemap); rendered into the app icon at build time
svg2png.js build-time helper: SVG → transparent PNG (used for the app icon)
cli.py mac-storage-dashboard CLI: run / app / install / doctor / uninstall
build_app.command builds dist/Mac Storage Dashboard.app from a clone
run.command double-click launcher (runs in Terminal)
release.command zips the app + prints the sha256 for the Homebrew cask
packaging/homebrew/ Homebrew cask template
tests/ sandbox integration test for the cleanup engine
docs/ screenshots
Roadmap
- Signed & notarized app bundle (so the app is trusted out of the box, no right-click-to-open).
- Scheduled scans and history graphs (snapshots are already collected in
data.json).
License
MIT — see LICENSE.
Metadata
Release files for mac-storage-dashboard 1.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mac_storage_dashboard-1.1.2.tar.gz | 57.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mac_storage_dashboard-1.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 113.0 kB
Release files / mac_storage_dashboard-1.1.2.tar.gz
| Download URL | mac_storage_dashboard-1.1.2.tar.gz |
|---|---|
| Size | 57.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c66d606c3bf5970b89b16abba8791775f402bf5aa417bc5d7755b326de980554
|
|
BLAKE2b-256 checksum How to use checksums |
72f39904a8c4322e684247bcfc90e57b84a4a7d74b35884c9a29c83e33fdaf52
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.
Transparency logRelease files / mac_storage_dashboard-1.1.2-py3-none-any.whl
| Download URL | mac_storage_dashboard-1.1.2-py3-none-any.whl |
|---|---|
| Size | 55.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b866f8ced418292965c05007bf6eae9280d3d94624cfc607d2f4699ce6ba4066
|
|
BLAKE2b-256 checksum How to use checksums |
ec28026b2fdf09ffc9e508d81f6f983ea0e8cee73063d11db3ab0ef7f2d029a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.
Transparency log