Find rebuildable development directories and exclude them from Time Machine.
The command is a dry run unless you pass --apply.
Requires macOS and Node.js 18.17 or later. There are no runtime dependencies.
npm start # scan your home directory
npm start -- ~/Projects # scan one directory
npm start -- ~/Projects --apply # add exclusions
npm start -- --revert --apply # remove matched exclusions
npm start -- --min-size 100MB --apply # ignore smaller candidates
npm start -- --skip cargo-target --apply # disable a ruleRun npm start -- --help for all options and
npm start -- --list-rules for
the complete rule set.
npm run uiThe interface lets you select individual directories before adding or removing
exclusions. It listens on 127.0.0.1.
To make tm-dev-exclude available outside the repository:
npm link
tm-dev-exclude --helpAfter linking, tm-dev-exclude [options] is equivalent to
npm start -- [options].
Rules cover dependency directories, build output, virtual environments, and
tool caches. Generic names need a matching project marker. For example,
target requires Cargo.toml or pom.xml.
The scanner does not follow symlinks, cross filesystem volumes, enter macOS app packages, or descend into version control metadata.
By default, the command writes Time Machine's exclusion extended attribute to each directory. This does not require administrator privileges. If a build tool recreates the directory, run the command again.
Sticky exclusions survive directory recreation:
sudo npm start -- --sticky --apply
sudo npm start -- --sticky --revert --applySticky exclusions are path-based and require administrator privileges.
Configuration is read from ~/.config/tm-dev-exclude/config.json or
~/.tm-dev-exclude.json.
Machine-specific paths can use TM_DEV_EXCLUDE_ROOTS and
TM_DEV_EXCLUDE_IGNORE. Both accept colon-separated paths:
export TM_DEV_EXCLUDE_ROOTS="$HOME/Projects:$HOME/work"
export TM_DEV_EXCLUDE_IGNORE="$HOME/work/do-not-touch:$HOME/stuff/don-not-touch"npm test
{ "roots": ["~/Projects"], "ignore": ["~/Projects/archive"], "skip": ["cargo-target"], "minSize": "50MB" }