- Rust 96.2%
- Shell 2.6%
- Makefile 1.2%
Pivot from a root LaunchDaemon that watched Spotlight via fs_usage to a user-level tool that remembers swept roots and re-sweeps on demand or schedule. - Remove libproc/fs_usage CPU watching, nix, plist, tracing deps - sweep [paths]: targeted recursive sweep; remembers roots - resweep: re-walk every remembered root (catches new junk dirs) - RootRegistry (sbg-core): JSON registry, nested-root normalisation - gitignore: register marker in enclosing repo's .git/info/exclude (worktree/submodule .git-file indirection handled), never touches tracked .gitignore -> markers never appear in git status - resilient sweep: per-dir errors counted, never abort (SIP caches) - install: user LaunchAgent runs resweep on StartInterval (no sudo) - state under ~/.local/state, config under ~/.config 19 tests green, clippy -D warnings clean, fmt clean. |
||
|---|---|---|
| crates | ||
| packaging/launchd | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CLAUDE.md | ||
| config.example.toml | ||
| install.sh | ||
| LICENSE-APACHE | ||
| LICENSE-MIT | ||
| Makefile | ||
| README.md | ||
| rust-toolchain.toml | ||
spotlightd-be-gone
A small macOS tool that stops Spotlight from wasting CPU and disk I/O indexing
directories that have no business being searchable — node_modules, Rust
target/, dist/build, __pycache__, .git, caches, and friends.
macOS Spotlight has no native pattern/glob exclusion. The only mechanism it
honours is a .metadata_never_index marker file dropped inside each directory
you want skipped. Maintaining those by hand across hundreds of churning build
dirs is hopeless. This tool does it for you — and remembers where it swept so
it can re-sweep later as new junk dirs appear.
It runs entirely as your user — no root, no sudo.
Why this exists: on a 128 GB machine that was bogging down under load, the culprit wasn't RAM — it was Spotlight re-indexing ~900 build/dependency directories (and tens of thousands of churning files) over and over.
What it does
- Targeted sweep —
sweep <dir>walks a directory recursively, classifies every subdirectory, and drops a.metadata_never_indexmarker into each junk one. The walk prunes: it never descends intonode_modules/target, so it's fast. - Remembers roots — every path you sweep is recorded, so…
- Resweep —
resweepre-walks every remembered root to catch junk dirs created since last time. Install the LaunchAgent and this runs on a schedule. - Git-aware — when a marker lands inside a git repo, the marker filename is
added to that repo's
.git/info/exclude, so it never shows up ingit status. Your tracked.gitignoreis never modified. - Ledger — every exclusion is recorded as JSONL so you can list and reverse them.
Classification
| Class | Examples |
|---|---|
dependency |
node_modules, .venv, vendor, Pods, site-packages |
build |
target, dist, build, __pycache__, DerivedData, .next |
cache |
.cache, anything under a Caches/ directory |
tmp |
tmp/temp, /var/folders |
vcs |
.git internals |
configured |
matched one of your junk_globs but no structural category |
protected |
matched a protect_glob — never excluded |
protect_globs always win, so e.g. a node_modules under ~/Documents is left
untouched. The markers only affect Spotlight — never git, builds, or your tools.
Install
git clone https://github.com/ZachHandley/spotlightd-be-gone
cd spotlightd-be-gone
cargo build --release
# one-shot, no install needed:
./target/release/spotlightd-be-gone sweep ~/code
# or install the scheduled resweep LaunchAgent (still no sudo):
./install.sh
Usage
spotlightd-be-gone sweep ~/code # exclude junk under ~/code, remember it
spotlightd-be-gone sweep --dry-run . # preview, write nothing
spotlightd-be-gone resweep # re-sweep every remembered root
spotlightd-be-gone status # index state, remembered roots, counts
spotlightd-be-gone list # every directory excluded so far
spotlightd-be-gone unmark <dir> # reverse one exclusion
spotlightd-be-gone forget <root> # stop re-sweeping a root
spotlightd-be-gone install # user LaunchAgent for scheduled resweep
spotlightd-be-gone uninstall # remove the LaunchAgent
State lives under ~/.local/state/spotlightd-be-gone/ (ledger + remembered
roots); config at ~/.config/spotlightd-be-gone/config.toml
(see config.example.toml). Set auto_apply = false
to make every command preview-only.
Undoing everything
Markers are plain files. To remove every one this tool created:
spotlightd-be-gone list | awk '{print $1}' | xargs -I{} spotlightd-be-gone unmark {}
or just delete .metadata_never_index files yourself — nothing else depends on
them. The .git/info/exclude entries are harmless to leave, or remove the
.metadata_never_index line by hand.
License
MIT OR Apache-2.0.