Find out what's taking up space on your Mac. DiskManager scans your whole drive in seconds, draws it as an interactive sunburst and treemap, and lets you delete what you don't need — including the ~70% of your disk that Finder refuses to show you.
Free, open source, native Swift. No subscription, no upsell, no paywalled delete button.
Because Finder cannot answer the question. It hides ~/Library, hides every
dot-folder, shows no folder sizes without Get Info on each one, and cannot rank
files by size.
On the machine this was built for, that adds up to 230 GB of 330 GB used being invisible:
| Location | Size | Visible in Finder? |
|---|---|---|
~/.cache (Hugging Face, uv, pip) |
67 GB | ❌ dot-folder |
~/Library |
110 GB | ❌ hidden by default |
~/.npm, .gradle, .ollama, .android |
46 GB | ❌ dot-folders |
/opt (Homebrew) |
17 GB | ❌ |
- Sunburst and treemap — see your whole disk at a glance, drill into any folder, switch views without losing your place.
- Biggest files — every large file on the volume in one ranked list.
- Hidden — opens directly on
~/Libraryand your dot-folders. - Dev Junk — finds
node_modules, Gradle, npm, uv, pip caches, Xcode DerivedData, Hugging Face and Ollama model weights, Android emulators, Docker images. Each one says what deleting it actually costs you. - Duplicate finder — byte-identical files, grouped, oldest copy marked.
- Search — by name, size, or "untouched for two years".
- Move and copy across volumes, with real progress on large files.
- Safe deletion — everything goes to the Trash by default. System and SIP-protected paths are refused outright.
- Space accounting — explains the gap between what it found and what macOS reports, instead of leaving it a mystery.
Grab the latest .dmg from Releases,
open it, and drag the app to Applications.
The app is ad-hoc signed and not notarized (notarization needs a paid Apple Developer account). macOS will refuse the first launch. Either:
- right-click the app → Open, then confirm, or
- run:
xattr -dr com.apple.quarantine /Applications/DiskManager.appYou only need to do this once.
Grant it under System Settings → Privacy & Security → Full Disk Access, then rescan. Without it macOS silently reports protected folders as empty, so your totals will be wrong rather than merely incomplete. The app detects this and tells you instead of quietly under-reporting.
- macOS 14 (Sonoma) or later
- Apple Silicon (arm64)
| DiskManager | DaisyDisk | GrandPerspective | OmniDiskSweeper | WhatSize | |
|---|---|---|---|---|---|
| Price | Free | $9.99–29.95 | Free / $2.99 | Free | $14.99 |
| Visual map | Sunburst + treemap | Sunburst | Treemap | ❌ none | Chart |
| Delete from app | ✅ | ✅ | ✅ | ✅ | ✅ |
| Duplicate finder | ✅ | ❌ | ❌ | ❌ | ✅ |
| Developer cache rules | ✅ | ❌ | ❌ | ❌ | ❌ |
| Hidden-space view | ✅ | ❌ | ❌ | ❌ | ❌ |
| Explains unaccounted space | ✅ | ❌ | ❌ | ❌ | ❌ |
Measured on a 460 GB Mac with 3.93M files:
| Full volume scan | 14.9 s (376–419% CPU) |
| Peak memory | 445 MB |
Accuracy vs du -skx |
exact — 289,789,825,024 bytes, both |
| Developer junk found | 173 GB |
| Duplicates found | 49.4 GB across 1,326 sets, in 20.6 s |
It isn't one folder. macOS lumps caches, logs, swap and APFS snapshots into that label, and they live all over the disk. DiskManager shows you the actual folders instead of a category, and reports snapshots and purgeable space separately.
Sparse files. Docker.raw claims 494 GB while occupying 19 GB — the rest was
never written. Analyzers that trust the apparent size report a single file
bigger than the whole disk. DiskManager measures allocated blocks and shows the
apparent size only to explain the difference.
Mostly yes, and the app tells you which. It separates caches that rebuild from
what's already on disk (node_modules → npm install) from ones that
re-download gigabytes (Hugging Face weights) from things that are genuinely
irreplaceable (Android emulator images, Docker volumes).
No. Items are staged in a tray with a running total, confirmed once, and moved to the Trash. Permanent deletion exists but sits behind a menu and a typed confirmation. System and SIP-protected paths are never removed.
That's the intent. DaisyDisk is a good-looking paid app with no duplicate finder, no developer-cache rules, and no hidden-space view. GrandPerspective is free but its interface dates to 2005. This aims to be free and modern and able to delete.
No Xcode required — Command Line Tools are enough.
git clone https://github.com/ashwinn-si/diskManager.git
cd diskManager
./Scripts/run.sh| Script | What it does |
|---|---|
Scripts/run.sh |
debug build → .app → launch |
Scripts/bundle.sh |
release build → ad-hoc signed DiskManager.app |
Scripts/dmg.sh |
icon → release bundle → DiskManager.dmg |
Scripts/test.sh |
full test suite (76 tests) |
Scripts/make-icon.swift |
regenerates Resources/AppIcon.icns |
Scripts/test.sh exists because swift-testing ships inside Command Line Tools
but SwiftPM doesn't add its framework path when Xcode is absent. Plain
swift test fails with no such module 'Testing'.
The scan engine has its own entry point, so it can be measured against du
without launching the app:
swift run -c release ScanCLI / --top 20 # largest files on the volume
swift run -c release ScanCLI ~ --junk # developer caches and build output
swift run -c release ScanCLI ~ --dupes # byte-identical files
swift run -c release ScanCLI / --account # space accounting vs. the OS
swift run -c release ScanCLI --volumes # mounted volumes and capacitygetattrlistbulk(2) returns ~1000 directory entries per syscall with sizes,
inode numbers and flags attached — versus one stat per file. Work is spread
over real threads, not Tasks, which would block Swift's cooperative pool on
the frontier's condition variable.
The tree is parallel arrays, not objects: ~39 bytes per node with interned names, so 3.9M nodes fit in a few hundred megabytes with no refcounting. Every parent sits at a lower index than its children, which makes subtree rollup a single reverse pass with no recursion.
Hard links are charged once, by inode. Symlinks and mount points aren't followed. Unreadable folders are recorded rather than skipped silently, which is what lets the accounting panel name the gap instead of leaving it unexplained.
The reconciliation reports a signed gap. A scan can find less than the volume holds (unreadable folders, sealed snapshots) or more (APFS clones share storage but carry a full allocation against every name), and the two need different words.
Duplicate detection funnels rather than hashing everything: group by size (free — the scan already knows every size), then hash 4 KB from each end, then full SHA-256 on the few that survive. Both hashing stages run across threads.
The app is not sandboxed, because App Sandbox forbids the whole-disk enumeration it exists to do.
Sources/
ScanKit/ engine — no UI, unit-tested, benchmarkable on its own
BulkEnumerator getattrlistbulk wrapper and record parser
ScanEngine threaded walk, work queue, shared accumulation
NodeStore struct-of-arrays tree + rollup
SunburstLayout wedges, culling, polar hit-testing
TreemapLayout squarified, nested layout
JunkRules developer cache rules
HiddenSpace what Finder will not show
DuplicateFinder size → head/tail hash → full SHA-256, in parallel
Search name/size/age filtering over the interned name blob
Trash deletion rules, Trash round trip, permanent delete
Transfer move/copy via copyfile(3), progress, conflict resolution
Reconciler space accounting, snapshots, Full Disk Access probe
ScanCLI/ terminal harness
DiskManagerUI/ SwiftUI views
DiskManagerApp/ @main entry
Free to use.
Keywords: mac disk space analyzer, macOS storage analyzer, free DaisyDisk alternative, what is taking up space on my Mac, find large files Mac, disk usage visualizer, System Data macOS, clean up Mac storage, sunburst disk map, treemap disk usage, duplicate file finder Mac.