Stop backing up files you'll never restore.
Every Time Machine snapshot copies your node_modules, .venv, target, DerivedData; gigabytes of files you can rebuild with one command. With git worktrees and AI coding agents spinning up parallel copies of every project, that waste compounds fast.
Asimov scans your home directory, finds dependency folders next to their config files, and tells Time Machine to skip them. Install once, run daily, forget it exists.
brew install django23/tap/asimov
brew services start django23/tap/asimovThat's it — Asimov runs at midday, every day. Prefer no Homebrew? See other install methods.
$ asimov --dry-run --stats
⏳ Scanning for dependency directories…
📦 Processing matches…
- Would exclude: ~/Code/myapp/node_modules (412M).
- Would exclude: ~/Code/myapp/.next (89M).
- Would exclude: ~/Code/api/.venv (1.2G).
- Would exclude: ~/Code/rust-cli/target (2.4G).
- Would exclude: ~/Code/worktrees/feature-auth/node_modules (1.6G).
- Would exclude: ~/Code/worktrees/feature-auth/.next (492M).
- Would exclude: ~/Code/worktrees/refactor-billing/node_modules (1.6G).
…
Would exclude 27 directories, totalling 18.4G.
--dry-run previews without changing anything. Drop the flag — and the --stats if you want it fast — to apply.
Asimov pairs each dependency directory with a sentinel config file. A folder is only excluded if its sentinel exists alongside it:
node_modules/→ requirespackage.jsonvendor/→ requirescomposer.jsonorgo.modtarget/→ requiresCargo.tomlorpom.xml
This means Asimov never touches a folder that just happens to share a common name. Safe to run anywhere in your home directory.
Supported ecosystems (30+ patterns)
| Ecosystem | Directories excluded |
|---|---|
| JavaScript / TypeScript | node_modules, .next, .nuxt, .angular, .svelte-kit, .turbo, .yarn, .parcel-cache, bower_components, elm-stuff |
| Monorepo | .moon/cache |
| Python | .venv, venv, .tox, .nox, __pypackages__, build, dist |
| Rust | target |
| Go | vendor |
| PHP | vendor |
| Ruby | vendor |
| Java / Kotlin / Scala | .gradle, build, target |
| .NET (C# / F#) | bin, obj |
| Swift / Apple | .build, Carthage, Pods, DerivedData |
| Dart / Flutter | .dart_tool, .packages, build |
| Elixir | deps, _build, .build |
| Clojure | target, .cpcache, .shadow-cljs |
| Haskell | .stack-work |
| OCaml | _build |
| Zig | .zig-cache, zig-out |
| R | renv |
| DevOps / IaC | .terraform, .terragrunt-cache, .vagrant, .direnv, cdk.out |
| Game dev | .godot |
| Global caches (opt-in) | ~/.cache, ~/.gradle/caches, ~/.m2/repository, ~/.npm/_cacache, ~/.nuget/packages, ~/.kube/cache |
Don't see your tool? You can teach Asimov your own directory + sentinel pairs in a couple of lines — no need to wait for a release. See Add your own patterns.
asimov [--dry-run] [--verbose] [--quiet] [--stats] [--no-read-cache] [--no-write-cache] [--help] [--version]
| Option | Description |
|---|---|
--dry-run |
Print what would be excluded without changing Time Machine |
--verbose |
Show all directories including already-excluded ones |
--quiet |
Suppress all output except errors |
--stats |
Show per-directory sizes and a total-space summary |
--no-read-cache |
Ignore cached state; re-discover and re-verify everything, then rebuild the cache |
--no-write-cache |
Run normally but don't persist any cache updates |
Asimov keeps a cache under ~/.cache/asimov/ so repeat runs are near-instant. The two flags above control it on independent axes — reading and writing:
--no-read-cache— "rebuild." Ignores everything cached, re-scans the filesystem, and re-verifies every directory against Time Machine, then writes a fresh cache.--full-scanis an alias.--no-write-cache— "don't touch state." Uses the fast cache to read, but persists nothing. Handy with--dry-run.- Both together = a fully stateless run that reads and writes nothing.
--no-cacheis an alias for this.
If you installed via Homebrew, brew services start django23/tap/asimov already set up a daily run. To trigger one immediately or stop the schedule:
launchctl kickstart gui/$(id -u)/com.django23.asimov # run now
launchctl bootout gui/$(id -u)/com.django23.asimov # stop scheduleManual and curl installers set up the same launchd job automatically.
Asimov works out of the box. To customize it, drop a config file at ~/.config/asimov/config. The most useful thing you can do here is teach it dependency directories of your own.
Using a tool Asimov doesn't know about yet? Add it yourself. Each pattern is a directory sentinel pair — exactly the same mechanism the built-ins use: the directory is excluded only when the sentinel file sits right beside it, so it's safe even for common folder names.
[sentinels]
extra = .cache my-tool.toml # exclude .cache only when my-tool.toml is its sibling
extra = generated codegen.yml # one "extra =" line per pattern
extra = dist *.podspec # glob sentinels work tooWant to turn a built-in off? List its exact pair under disabled:
[sentinels]
disabled = vendor Gemfile # stop excluding Ruby's vendor/ directoriesGlobal tool caches in your home directory (~/.cache, ~/.gradle/caches, …) are left alone by default. Opt in, and add paths of your own:
[fixed_dirs]
enabled = true # exclude the built-in global caches
extra = ~/my-build-cache # plus any paths you name (always excluded when they exist)curl (no Homebrew):
curl -fsSL https://raw.githubusercontent.com/django23/asimov/main/scripts/install-remote.sh | bashFrom source:
git clone https://github.com/django23/asimov.git --depth 1
cd asimov && make installbrew uninstall asimov # Homebrew
rm ~/.local/bin/asimov # curl install
launchctl bootout gui/$(id -u)/com.django23.asimov # stop schedule
make uninstall # source installSee UPGRADING.md for migrating from v0.4.x or the original asimov.
Asimov was originally created by Steve Grunwell. This fork is actively maintained at django23/asimov with performance improvements, config file support, and expanded ecosystem coverage.
See CONTRIBUTING.md for setup and guidelines. Security issues: see SECURITY.md.