Single binary · zero runtime deps

Run your tasks.
Trust your cache.

A fast, single-binary, polyglot task runner with a content-addressed cache that captures outputs and shares them across machines.

Read the docs
What it does

Everything a runner should be, and the cache nobody else ships.

Most runners stop at "run these commands in order". yatr keeps going: it remembers what it ran, restores what it made, and proves it has not been tampered with.

Content addressed

Hashes inputs, not clocks

The cache key is a BLAKE3 hash of sources, command, working directory, and declared outputs. Same inputs, guaranteed hit. No mtime guessing.

sources+ command+ outputs blake3

Captures & restores outputs

On a hit, yatr does not just skip. It restores the actual artifacts from a content store, so a cached build leaves the same files behind.

Remote & shared cache, with REAPI

Push and pull cache entries over HTTP, or speak the REAPI protocol to talk to bazel-remote and BuildBuddy. Your laptop hits what CI already built.

Signed against poisoning

Every cached result carries a keyed BLAKE3 signature. A tampered entry from a shared cache is rejected, not trusted blindly.

Affected detection

Point yatr at a git ref and it runs only the tasks your changes touched. Monorepo friendly, no plugin required.

Toolchain pinning

Pin language runtimes in [toolchain]. A fresh checkout downloads them and runs green. No "works on my machine".

Sandboxed WASM plugins

Extend yatr with capability-sandboxed WebAssembly. Write them in Rust with the PDK, or load one straight from a GitHub release.

Editor intelligence

A language server gives live diagnostics, a task outline, and a published JSON Schema for yatr.toml.

Why the cache is different

A cache that tells the truth.

Make trusts timestamps. Most runners trust nothing, or cache by hope. yatr derives a key from what actually went into a task, stores the outputs by content, and signs the lot.

Move it between machines and the key still matches, because it hashes relative paths. So a warm rebuild is honest: it is the build CI already proved, restored, not re-run.

yatr.toml
[tasks.build]
run = ["cargo build --release"]
sources = ["src/**", "Cargo.toml"]
outputs = ["target/release/app"]
deps = ["codegen"]
 
# change nothing, run again: restored in 0.12s
Measured, not claimed

Fast on the cold path. Instant on the warm one.

Numbers from the reproducible suite in the repo, run against make, just, and task. Reproduce them yourself with one script.

~8 ms
Startup overhead. Beats make, matches just, on a real task graph.
~14×
Warm rebuild speedup versus running the same graph with no cache.
1.8×
Faster on uneven graphs, thanks to a ready-queue scheduler over level barriers.
Where it sits

Simpler than cargo-make. More than just.

yatr lives in the sweet spot: the ergonomics of a small runner, the cache fundamentals of a build system, and none of the Bazel ceremony.

Capability make just cargo-make yatr
Simple config×~
Parallel execution×
Content-addressed caching××~
Captures & restores outputs×××
Remote / shared cache×××
Signed cache×××
Affected detection××~
Toolchain management×××
Sandboxed plugins×××
Editor LSP×~×
Get the herd moving

One binary. Drop in a yatr.toml. Done.

Install from crates.io, or build the latest from source. The plugin PDK ships as its own crate.

$ cargo install yatrfrom crates.io
$ cargo install --git ...cargopete/yatrlatest main
$ cargo add yatr-pluginwrite a plugin