Skip to content

Installation

lu-cleaner is a single Go binary. It installs no daemon, launch agent or background service, and it never asks for sudo. Its own files live in exactly two places, both created only when needed: the configuration file (when you create one) and the cleaning history (after your first real cleanup).

Requirement Details
macOS 12 Monterey or later Apple Silicon or Intel. lu-cleaner is macOS-only: it relies on APFS, getattrlistbulk, xcrun simctl and the macOS layout of ~/Library.
Go 1.25 or later Only needed to build and install the binary.
git Used by the worktree scanner (git worktree list, git worktree remove). Without it, worktrees are simply not scanned. The Xcode Command Line Tools provide it.

Everything else is optional: Xcode, Android Studio, Docker, Node.js version managers and AI tools are only inspected when they are installed.

This is the recommended way:

Terminal window
go install github.com/ludwig-pro/lu-cleaner/cmd/lu-cleaner@latest

Go places the binary in $(go env GOPATH)/bin, which is usually ~/go/bin (or in $GOBIN if you set it). If your shell cannot find lu-cleaner afterwards, add that folder to your PATH:

Terminal window
echo 'export PATH="$PATH:$(go env GOPATH)/bin"' >> ~/.zshrc
source ~/.zshrc

Check the installation:

Terminal window
lu-cleaner version

Use this to try an unreleased change or to contribute.

  1. Clone the repository:

    Terminal window
    git clone https://github.com/ludwig-pro/lu-cleaner.git
    cd lu-cleaner
  2. Build bin/lu-cleaner. The version is taken from git describe:

    Terminal window
    make build
    ./bin/lu-cleaner scan --summary
  3. Install it into $(go env GOPATH)/bin:

    Terminal window
    make install

make run ARGS="scan --summary" builds and runs in one step, and make test runs the unit tests. See Contributing for the development workflow.

lu-cleaner is long to type. make install suggests luc:

Terminal window
echo 'alias luc=lu-cleaner' >> ~/.zshrc
source ~/.zshrc
luc scan --summary

The rest of this documentation spells out lu-cleaner in full.

macOS privacy protection (TCC) prevents any app from reading a few folders unless you grant it Full Disk Access. lu-cleaner works without it, but a few folders are then out of reach:

Folder Without Full Disk Access
~/.Trash The Trash is listed as Trash (size unknown — needs Full Disk Access). Cleaning it asks Finder to empty it instead of deleting the files directly (Finder may ask you for an Automation permission). lu-cleaner doctor reports the Trash size as unknown.
~/Library/Application Support/MobileSync/Backup iPhone and iPad backups made by Finder are listed as iPhone/iPad backups (size unknown). They are report-only either way: lu-cleaner never deletes device backups.
Other apps' containers: ~/Library/Containers/<app>, ~/Library/Group Containers/<group> Never read, measured or cleaned. On macOS 14 and later, touching them would open a system permission prompt and block the scan until someone answers. Catalog entries stored there (Docker Desktop logs, the Microsoft Teams cache, the Apple Music artwork cache…) are listed as report-only with the warning needs Full Disk Access, the Docker Desktop and OrbStack disk images are not shown, and analyze shows these folders as 🔒 app container — needs Full Disk Access.

lu-cleaner analyze also warns when some entries are unreadable and their sizes are partial.

To grant it:

  1. Open System Settings → Privacy & Security → Full Disk Access.
  2. Enable the app you run lu-cleaner from: Terminal, iTerm2, Ghostty, Warp, or the editor whose integrated terminal you use. Add it with + if it is not listed.
  3. Quit and reopen that app so the permission applies.

Run the same command again to fetch the latest version:

Terminal window
go install github.com/ludwig-pro/lu-cleaner/cmd/lu-cleaner@latest

From a clone, pull and reinstall:

Terminal window
git pull
make install

Your configuration and history are kept.

Before removing the binary, check where your files live. The configuration moves if you set LU_CLEANER_CONFIG or XDG_CONFIG_HOME, the history if you set XDG_STATE_HOME:

Terminal window
lu-cleaner config path # the configuration file
lu-cleaner config show # also prints the history file

Then remove the binary, the configuration and the history:

Terminal window
rm "$(command -v lu-cleaner)"
rm -rf ~/.config/lu-cleaner # config.toml, if you created one
rm -rf ~/.local/state/lu-cleaner # history.jsonl

Finally, delete the alias luc=lu-cleaner line from ~/.zshrc if you added it. lu-cleaner leaves nothing else behind.