Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

macspace

A developer-focused disk-space visualizer for macOS on Apple Silicon.

Author: Nikita Y · (C) 2026 NikitaY.com

macspace walks the APFS data volume (or a focused subset), shows on-disk allocated bytes, and opens a colourful terminal UI: directory navigator, squarified treemap, and category dashboard.

Nothing is deleted. The d key builds a dry-run reclaim plan only. Execute() always returns an error.

macspace --dev          # start here — caches, hidden folders, Homebrew var
macspace --sql          # database data dirs only
macspace --dev --sql    # both (typical “where did 200 GiB go?”)

Requirements

  • macOS on Apple Silicon (Darwin + CGO_ENABLED=1)
  • Go 1.27+
  • A terminal that can render Unicode / colour (the TUI uses Bubble Tea + Lipgloss)

Intel Macs are not a supported target.

Install

git clone https://github.com/nikitaycs50/macspace.git
cd macspace
make
./bin/macspace --help

Or without Make:

CGO_ENABLED=1 go build -o bin/macspace ./cmd/macspace

Put bin/macspace on your PATH if you want the short command.

Efficient recipes

Full-volume scans are slow and need Full Disk Access. Prefer a profile unless you really need everything.

Command What it does
macspace --dev $HOME plus Homebrew /opt/homebrew/var (and /usr/local/var if present). Skips Applications, Photos, Music, Movies, Public, .app bundles, and a few standard Library trees (Mail, iCloud Drive, Photos). Keeps caches, node_modules, .venv, Library/Developer, Docker leftovers, hidden .* dirs.
macspace --sql Only database-related locations that exist: Postgres.app / Homebrew Postgres / MySQL / Mongo, Docker/OrbStack VMs, TablePlus, DBeaver, pgAdmin, RedisInsight, and matching ~/Library/Application Support names.
macspace --dev --sql Union of the two.
macspace --home Whole home folder, including Desktop and Documents.
macspace /System/Volumes/Data — entire data volume. Grant Full Disk Access first.
macspace /path One directory. Combines with --dev / --sql skip rules when those flags are set.

Headless:

macspace --dev scan --json report.json
macspace --sql scan --json -          # JSON on stdout; progress on stderr
macspace --dev dup                    # duplicate large files
macspace doctor                       # FDA, snapshots, volume identity
macspace rules                        # classifier + safety levels
macspace --about

TUI

Long scans show status bars (dirs / files / bytes), a pulse or fill bar, hourglass spinner, current path, and a rough ETA on full-volume walks. Headless commands reuse the same bars on stderr when it is a TTY.

Key Action
1 / 2 / 3 Navigator / treemap / categories
j k Move
Enter / Descend (treemap: zoom in)
/ Backspace Ascend
u Treemap zoom out
space Mark / unmark
s n m Sort by size / name / mtime
/ Fuzzy path filter
f Filter panel (age / size / category)
d Dry-run reclaim plan for marked items
? Help
q Quit

Click a treemap cell to zoom.

How sizes work

  • Reported size is allocated bytes on disk, not Finder’s “apparent” size.
  • Hardlinks are counted once.
  • APFS clones have no public per-file API; leftover volume space after a full scan is shown as shared/cloned residual.
  • Small files collapse into a single "(N small files)" node unless you pass --all-files. Default threshold: 64 KiB (--min-file).
  • Local Time Machine snapshots and mount points are not descended into.

Volume-root scans persist a warm index at ~/.local/state/macspace/<volume-uuid>.idx and try an FSEvents delta on the next run. --rescan forces a full walk. Profile scans (--dev / --sql / --home) do not overwrite that volume index.

Full Disk Access

Without FDA, TCC-protected trees (Mail, Safari, Messages, …) become explicit inaccessible nodes instead of silent holes.

  1. System Settings → Privacy & Security → Full Disk Access
  2. Add the macspace binary
  3. Re-run (macspace doctor confirms the probe)

Safety

Deletion is not implemented in this version.

  • internal/reclaim.Execute always returns ErrNotImplemented.
  • CI greps the tree for os.Remove, RemoveAll, Unlink, and rm outside internal/reclaim.
  • Dry-run plans still classify paths (safe / manual / dangerous) and attach warnings (dirty git worktree, open files, recent mtime, toolchain paths). Dangerous categories such as Documents, Desktop, and Photos are never suggested.

Flags

-h, --help          colourful usage
--about             version, design notes, safety
--dev               developer profile
--sql               database profile
--home              scan $HOME
--rescan            ignore the warm index
--workers N         walker threads (default 2× CPU)
--min-file SIZE     small-file collapse (default 64K)
--all-files         do not collapse small files
--json FILE         write a JSON report; no TUI (`-` = stdout)

Build & test

make              # bin/macspace
make test         # go test ./...
make vet
make verify       # du check + safety grep + treemap + Execute stub
make bench

CGO_ENABLED=1 is required (getattrlistbulk via cgo).

Layout

cmd/macspace/          CLI entry
internal/fsx/          getattrlistbulk, volume UUID, snapshots, FDA probe
internal/scan/         parallel walker, hardlink dedupe, JSON export
internal/tree/         packed 64-byte node arena
internal/rules/        embedded rules.yaml classifier
internal/profile/      --dev / --sql root + skip plans
internal/tui/          navigator, treemap, dashboard
internal/index/        mmap index + FSEvents delta
internal/reclaim/      dry-run only
internal/dedupe/       size → xxh3 sample → BLAKE3
internal/cliui/        --help / --about / stderr progress
internal/safetest/     no-delete grep

Author

Written by Nikita Y.

(C) 2026 NikitaY.com

License

(C) 2026 NikitaY.com. All rights reserved until a license file is added.

Releases

Packages

Contributors

Languages