A fast, native disk-usage treemap for Apple Silicon Macs — WizTree-style boxes, built with a Rust scanning core and a SwiftUI front end.
Most disk scanners issue one lstat syscall per file — for a million files,
that's a million kernel round-trips. Storage Manager's Rust core uses
getattrlistbulk(2), a macOS syscall that returns name, type, size, inode,
and link count for a whole batch of directory entries at once, cutting
syscalls by orders of magnitude. Directories are walked in parallel across all
cores with rayon.
Measured on an M-series MacBook (12 cores, ~956k files, 296 GB home directory, warm cache):
| Tool | Scan time |
|---|---|
du -sk |
22.7 s |
naive parallel read_dir + lstat |
3.5 s |
| Storage Manager | ~2.2 s |
(WizTree on Windows reads NTFS's Master File Table directly; APFS has no user-readable equivalent, so a filesystem walk is the floor on macOS — this is about as close to it as it gets.)
- Sizes are allocated on-disk bytes (
ATTR_FILE_ALLOCSIZE), matchingdubyte-for-byte — sparse files, APFS clones, and compressed files are not overreported. - Hardlinked files are counted once (deduped by device + inode).
- Symlinks are never followed and count as zero.
- Filesystem boundaries are respected; scanning
/correctly handles macOS's firmlink-stitched System/Data volume split without double-counting.
- Auto-populated drive picker (mounted volumes + home directory)
- Squarified-style treemap: box area ∝ size; click a folder to drill in, breadcrumb to climb back out
- Hover for exact sizes; right-click any box to Copy Path or Reveal in Finder
- Scan timing in the status bar
scanner/ Rust static library
src/lib.rs getattrlistbulk walker, rayon parallelism,
C FFI: scan_path() -> JSON, free_string()
StorageManager/ Swift package
Sources/CScanner/ C header + modulemap bridging the Rust lib
Sources/StorageManager/ SwiftUI app: treemap layout + UI
The two halves talk over C FFI: Rust serializes the size tree to JSON and hands
Swift a C string; Swift decodes it with Codable. Rust allocates, Rust frees.
Requires Rust (any recent stable) and Xcode command-line tools.
cd scanner && cargo build --release
cd ../StorageManager && swift build -c releaseThe result is a single self-contained binary (the Rust lib is statically
linked). To wrap it as an app bundle, see make-app.sh.
macOS blocks apps from reading most directories outside your home folder — no error, just silently missing data. For accurate full-drive scans, grant the app System Settings → Privacy & Security → Full Disk Access.
The Rust core has a test suite covering du parity (byte-exact), edge cases
(unicode and JSON-hostile filenames, hardlinks, symlink loops, permission-denied
directories, deep nesting, sparse files), scan determinism, and FFI leak stress:
cd scanner && cargo test --release -- --test-threads=1