2026
A native macOS app that maps every folder on your disk once, keeps that map current from the macOS change log, and turns it into a short list you can clean without breaking anything.
Ballast is a native SwiftUI app for macOS 26 that answers three questions
in order: where did the space go, what can go safely, and will anything break?
It is aimed at everyone who runs out of disk, and especially at developers,
whose disks fill with node_modules, build output, toolchains, simulators and
package-manager caches — things that are safe to throw away but hard to find.
Ballast walks /System/Volumes/Data once (not /, so firmlinked folders like
/Users count once) and stores every folder in a SQLite index, with sizes
taken from what is actually allocated on disk — what du reports — and hard
links counted once. Every later launch replays the FSEvents log macOS already
keeps and rechecks only the folders that changed. If that log can't be trusted
— events dropped, IDs wrapped, the root changed — it falls back to a full scan
instead of guessing.
External drives and other volumes get their own index, scanned only when you ask. APFS and Mac OS Extended drives are updated from their own change log; ExFAT and FAT start a new log on every mount, so Ballast rescans them and says so.
Every item gets one of four verdicts, checked again at the moment it is deleted:
| Verdict | Examples |
|---|---|
| Safe | App caches, node_modules, DerivedData, downloaded installers |
| Quit the app first | A browser's cache while the browser is open |
| Check first | Git repositories, tool folders, apps |
| Protected | App data, Keychains, Mail, Photos, .ssh, .git |
The default is Move to Trash, and every cleanup is logged so Put Back
can restore it — never over something new that has appeared at the same path.
Tools with their own cleanup command (npm cache clean, go clean -modcache,
brew cleanup) run that command instead of deleting files. Ballast never asks
for admin rights to delete.
target/ only next to a Cargo.toml, .next only next to a package.json
or Next config — never by name alone.brew and git.The index, growth history and cleanup log stay in
~/Library/Application Support/Ballast. Update checks (Sparkle) and anonymous
usage data are both off until you allow them; usage events carry only values
from fixed lists, booleans and ranges — never paths, names or exact sizes.
Releases are on GitHub as Ballast.zip. Builds are signed ad-hoc and not
notarized, so macOS asks you to approve the first launch. Full Disk Access is
recommended so privacy-protected folders can be measured.
Swift 6, SwiftUI, SQLite, FSEvents, WidgetKit, App Intents, Sparkle. Licensed under the GNU AGPL v3.