Skip to content

Quick start

This tour takes about five minutes. Nothing is deleted before step 4, and step 4 only removes the items smart select recommends (safe caches and regenerable data you have not used for a while) because you ask for it with --smart. If you would rather choose item by item, the dashboard of step 2 opens with nothing selected.

It assumes lu-cleaner is installed. The sizes below are illustrative.

  1. See where the space goes

    Terminal window
    lu-cleaner scan --summary

    scan is read-only. It runs every scanner and prints one line per category:

    $ lu-cleaner scan --summary CATEGORY SIZE ITEMS RECOMMENDED 🌳 Worktrees 42.8 GB 31 11.6 GB (9) 📦 Project artifacts 36.4 GB 118 9.20 GB (38) 📱 iOS Simulators 24.1 GB 14 8.70 GB (6) 🔨 Xcode 18.6 GB 12 15.2 GB (5) 🤖 Android 14.3 GB 19 3.40 GB (7) 🧠 AI tools 12.9 GB 57 4.10 GB (22) 🟨 JS toolchain 17.2 GB 48 12.3 GB (27) 🧩 IDEs 3.10 GB 15 2.60 GB (11) 💻 System 6.40 GB 25 1.90 GB (6)   Total 176 GB in 331 items · ★ 69.0 GB recommended (131 items) Disk: 43.0 GB free of 494 GB (91% used) → run: lu-cleaner clean --smart

    • SIZE is what cleaning every item of the category would free (report-only entries excluded).
    • RECOMMENDED is what smart select would pick, with the number of items. The ★ marks the same items in the detailed report.

    The first scan can take a minute or more on a busy machine: it measures thousands of directories. Drop --summary to list the 15 largest items of each category, add --all to list everything, or narrow with -c:

    Terminal window
    lu-cleaner scan -c worktrees,artifacts
  2. Open the dashboard

    Terminal window
    lu-cleaner

    Without a command, lu-cleaner opens the interactive dashboard. Categories fill in as scanners finish. When the scan is done, nothing is selected: the footer says "nothing selected" and the status line reminds you how to choose. Select what you want to remove with space (an item, or a whole category), or press a to select the recommended items and look at what it picked. Then press d. Nothing is deleted until you confirm.

    Key Action
    ↑ ↓ / enter Move / open a category
    space Select or unselect the item under the cursor (on a category: everything but caution items)
    a Smart select the current view: select the recommended items
    d Clean the selection (shows the total and asks for confirmation)
    ? / q Help / quit

    Press q to leave without touching anything. Your first cleanup walks through every screen, and Keyboard shortcuts lists every key.

  3. Rehearse the recommended cleanup

    Terminal window
    lu-cleaner clean --yes --smart --dry-run

    --yes cleans without the picker, --smart keeps only the recommended items, and --dry-run (-n) deletes nothing. The output is the exact plan, followed by what would happen:

    $ lu-cleaner clean --yes --smart --dry-run 🌳 Worktrees 11.6 GB · 9 items · ★ 11.6 GB recommended   NAME SIZE AGE RISK RECO PATH   my-app · feature/login 2.40 GB 3w moderate ★ ~/.codex/worktrees/a1b2/my-app   shop-app · fix/cart-badge 1.90 GB 2w moderate ★ ~/.cursor/worktrees/shop-app/k3m   …   📦 Project artifacts 9.20 GB · 38 items · ★ 9.20 GB recommended   NAME SIZE AGE RISK RECO PATH   shop-app › node_modules 1.42 GB 3mo moderate ★ ~/dev/shop-app/node_modules   shop-app › android/app/build 1.20 GB 3mo safe ★ ~/dev/shop-app/android/app/build   …   Plan: 131 items · 69.0 GB (dry run)   Dry run: nothing was deleted — 130 items would free 67.7 GB.   iPhone 11 · iOS 16.4 (unavailable): would run: xcrun simctl delete 5A1F0C2E-7B3D-4E8A-9C61-2F4B8D0E1A37 Skipped: 1   - codex:my-app › node_modules: in use: process 51234 runs a program or library from ~/.codex/worktrees/a1b2/my-app/node_modules

    A dry run re-runs every last-moment check of a real run without deleting anything: the safety guard, running apps, files in use, and the git checks of a worktree removal (lock, uncommitted changes, commits on no branch, nested repositories). That is why it can already report skipped items: here an agent started running tests in a worktree after the scan, so its node_modules is in use.

  4. Clean

    Terminal window
    lu-cleaner clean --yes --smart

    lu-cleaner rescans, prints the plan again, then cleans. The summary ends with two numbers:

    $ lu-cleaner clean --yes --smart   … ✓ 130 items cleaned · 67.7 GB freed (estimated)   Disk free: 43.0 GB → 110 GB (67.2 GB measured) Skipped: 1   - codex:my-app › node_modules: in use: process 51234 runs a program or library from ~/.codex/worktrees/a1b2/my-app/node_modules

    Estimated is the sum of what the cleaned items were expected to free. Measured is the change in free space reported by the file system before and after. A small gap is normal (other apps write to disk meanwhile). A large one means something still holds the space: see the next step.

    With --trash, files and folders are moved to the Trash instead: the summary counts them apart (moved to the Trash), never as freed, and worktrees and command items are skipped, since they cannot be undone.

    To clean only part of the recommendation, combine --smart with a category:

    Terminal window
    lu-cleaner clean --yes --smart -c artifacts,js
  5. Check the result with doctor

    Terminal window
    lu-cleaner doctor

    doctor explains why freed space does not always show up: APFS local snapshots, files waiting in the Trash, apps that keep deleted files open. It also repeats the scan summary by category, and never deletes anything.

    $ lu-cleaner doctor Disk   ██████████████████████░░░░░░░░ 78% used · 110 GB free of 494 GB   APFS local snapshots (1)   com.apple.TimeMachine.2026-09-29-093012.local   They pin the blocks of deleted files: that space comes back only when they   expire (about 24h) or are thinned. To reclaim it now (lu-cleaner never runs these):   tmutil thinlocalsnapshots / 999999999999 4   sudo tmutil deletelocalsnapshots 2026-09-29-093012   Trash   4.20 GB in 312 files — empty it to free the space   Running apps that block cleaning   Xcode DerivedData, Archives and device support are in use …

  6. Review what was done

    Terminal window
    lu-cleaner history

    Every real cleanup, from the dashboard or from clean --yes, is appended to ~/.local/state/lu-cleaner/history.jsonl. Dry runs are not recorded. The newest 30 entries are shown; --limit changes that, and --limit 0 shows everything.

    $ lu-cleaner history --limit 4 TIME STATUS METHOD SIZE FREED NAME PATH/COMMAND 2026-09-29 10:42 done delete 1.42 GB 1.42 GB shop-app › node_modules ~/dev/shop-app/node_modules 2026-09-29 10:42 done worktree 2.40 GB 2.40 GB my-app · feature/login ~/.codex/worktrees/a1b2/my-app 2026-09-29 10:42 done command 310 MB 310 MB iPhone 11 · iOS 16.4 (unavailable) $ xcrun simctl delete 5A1F0C2E-7B3D-4E8A-9C61-2F4B8D0E1A37 2026-09-29 10:42 skipped delete 1.28 GB codex:my-app › node_modules ~/.codex/worktrees/a1b2/my-app/node_modules   ! in use: process 51234 runs a program or library from ~/.codex/worktrees/a1b2/my-app/node_modules   Showing the last 4 of 131 entries (--limit 0 for all). Total freed: 67.7 GB over 130 cleaned items (~/.local/state/lu-cleaner/history.jsonl)

    FREED is what was really freed: less than SIZE when the data is shared with other files (hardlinks or APFS clones), empty for skipped items. Moves to the Trash free nothing until you empty it, so they are totalled apart.