salsa-rs/salsa: Incremental Computation in Rust
A generic framework for on-demand, incrementalized computation. Inspired by adapton, glimmer, and rustc's query system.
At a glance
- What is it?
- A Rust framework that turns your program into a set of memoized queries and recomputes only what changed. It is aimed at compilers, language servers and other tools that re-run the same analysis after every edit.
- Who is it for?
- Adopt salsa if you are building a Rust tool that re-runs the same derivations after small edits, such as a compiler, language server or build graph, and you can express those derivations as pure functions over typed inputs. Do not adopt it for one-shot batch jobs with no reuse, or where your logic needs side effects inside queries, since the README describes functions as pure with no side effects.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What salsa-rs/salsa actually solves
The README states the key idea plainly: you define your program as a set of queries, where each query behaves like a function from a key of type K to a value of type V. Queries come in two kinds. Inputs are the base inputs to the system, and you can change them whenever you like. Functions are pure transformations of those inputs into other values. Results are memoized, and when an input changes salsa works out when a memoized value can be reused and when it has to be recomputed.
That is a narrow problem with a large audience. Any tool that answers the same question repeatedly while the underlying data drifts, a type checker after a keystroke, a linker after a rebuilt module, a linter after a save, pays the full cost of recomputation unless something tracks dependencies for it. Salsa exists so that the tracking is not hand-written per project. The repository's own examples, examples/calc/ and examples/lazy-input/, are the smallest illustrations of that shape.
Inputs, functions and the memoization mechanism
The data flow is a graph. Inputs sit at the leaves. Functions read inputs or other functions and produce values, and each result is stored so a later call with the same key returns the cached value instead of re-running the body. When an input changes, salsa does not throw the whole cache away. It walks the dependents and decides which memoized entries are still valid.
The Cargo.toml shows how the machinery is assembled. salsa depends on hashbrown, hashlink, indexmap, intrusive-collections, thin-vec and smallvec, which is the shape of a dependency graph stored in hash maps and intrusive lists rather than a plain call stack. The optional rayon dependency and the parallel map comment indicate that some work can be spread across threads. The optional inventory dependency is described as automatic ingredient registration, and it is on by default, so the generated glue for your queries is wired up without a manual registry call. The persistence feature pulls in serde and erased-serde, which suggests cached values can be serialized, though the README does not document the persistence workflow.
Procedural macros live in components/salsa-macros, and there is a second component, salsa-macro-rules. The macros are what let you declare queries in ordinary Rust instead of writing the memoization layer yourself, and the default feature set includes macros, so the common setup needs no feature juggling.
Installing salsa and running a first query
Salsa is published on crates.io as the salsa crate, and the README points to docs.rs/salsa for the released API docs. Add it to a Cargo project the normal way. The version below matches the package version in the repository's Cargo.toml.
[dependencies]
salsa = "0.28.4"The README says the way to learn the API is the heavily commented examples under examples/ and the Salsa book at salsa-rs.github.io/salsa, which also has a Chinese translation at rust-chinese-translation.github.io/salsa-book. A first real use is to read examples/calc/, which is the smallest complete program in the repository, then copy its shape into your own crate: declare your inputs, declare your functions, and let the macros generate the storage.
The repository's own test entry points are in the justfile, which is the fastest way to see the framework exercised end to end if you clone it rather than depend on it.
cargo test --workspace --all-targets --no-fail-fastThat command runs the workspace tests. The justfile also defines a miri target and a shuttle target, the latter running cargo nextest with the shuttle feature against the parallel test, which is how the project exercises its concurrency behaviour. None of these are needed to use salsa as a dependency; they matter if you plan to modify the framework itself.
Where salsa is the wrong tool
The README is explicit that functions are pure, with no side effects. That is a real constraint, not a style note. If your derivation writes a file, opens a socket, or mutates shared state, it does not fit the query model without being restructured so the effect happens outside the query and only the value is memoized. Teams that try to keep side effects inside queries will fight the framework.
The Cargo.toml description calls salsa an experimental framework. The version line is 0.28.4, still below 1.0, and the project publishes salsa, salsa-macros and salsa-macro-rules in lockstep, as the release list shows with salsa-v0.28.4 and salsa-macros-v0.28.4 landing the same day. Depending on salsa means accepting that the macro-generated surface can shift between minor versions, and that an upgrade may touch every query declaration in your crate.
Salsa also assumes there is reuse to be had. A program that runs once over a fixed input and exits gains nothing from a dependency graph; the bookkeeping is pure overhead. The same applies when the working set is tiny enough that recomputation is cheaper than tracking. Salsa pays off when derivations are expensive and edits are small, and the README's framing of inputs being changed and memoized values being reused is the whole justification for it.
How salsa differs from a hand-rolled cache or rustc's query system
The README credits adapton, glimmer and rustc's query system as inspirations. rustc's query system is the closest relative: it is the same idea of memoized queries with dependency tracking, but it is built into the compiler, not usable as a library, and it is shaped around rustc's own interning, its diagnostics and its incremental on-disk cache. Salsa is the general-purpose extraction of that pattern, which means you get the dependency graph without the compiler.
Against a hand-rolled cache, the difference is what happens on invalidation. A HashMap keyed by input plus a manual clear is simple until one input feeds three derivations and only two of them are affected. Salsa maintains the edges for you and decides reuse per memoized value, which is the part that is tedious and error-prone to write by hand. The cost is that you give up direct control of the storage, and the dependency edges are inferred from what your query bodies actually read.
Against a general build system, the difference is granularity. A build system tracks files and commands. Salsa tracks typed values in memory, so a query can depend on a parsed AST rather than the bytes of a source file, and a change that does not alter the parsed result can stop propagating earlier.
Maintenance, releases and the licence
The repository is not archived, and the last push was on 2026-09-23, one day before the release of salsa-v0.28.4 on 2026-09-18. There is a CHANGELOG.md at the top level and release-plz.toml, so releases are automated: the README's contributing section says that updating the version field in Cargo.toml and pushing causes GitHub Actions to publish the crates to crates.io automatically. Renovate is configured as well, which points to routine dependency updates.
The upgrade cost is the version coupling. salsa, salsa-macros and salsa-macro-rules share a version number, and the macros are what generate the code your crate compiles against, so a bump in salsa is a bump in the generated surface. Pinning an exact version and reading CHANGELOG.md before moving is the practical approach. The FAQ.md file at the top level is the place to check for known rough edges before filing an issue.
On licensing, the repository ships LICENSE-APACHE and LICENSE-MIT, and the metadata lists Apache-2.0. The dual-licence layout is the usual Rust convention, and it matters for redistribution: Apache-2.0 carries an explicit patent grant and notice requirements, while MIT is shorter and more permissive. Which one applies to your use depends on how you comply, and that is a question for your own legal review rather than something the repository decides for you.
Editorial conclusion
Adopt salsa if you are building a Rust tool that re-runs the same derivations after small edits, such as a compiler, language server or build graph, and you can express those derivations as pure functions over typed inputs. Do not adopt it for one-shot batch jobs with no reuse, or where your logic needs side effects inside queries, since the README describes functions as pure with no side effects. Before committing, read the heavily commented examples in the repository and the Salsa book, then verify that the version you pin matches the salsa-macros version, because the crates are released together and the framework is described as experimental in its own Cargo.toml.
Frequently asked questions
What is salsa-rs/salsa in Rust?
It is a generic framework for on-demand, incrementalized computation, according to the README. You define your program as a set of queries, some of them inputs and some pure functions, and salsa memoizes the results so that changing an input recomputes only what is affected.
How do I install salsa-rs/salsa?
It is published on crates.io as the salsa crate; the package version in the repository's Cargo.toml is 0.28.4. Add salsa to the dependencies section of your Cargo.toml, then follow the examples under examples/ and the Salsa book.
Does salsa-rs/salsa support parallel execution?
The default feature set includes rayon, and the Cargo.toml comments the rayon dependency as parallel map. The repository also has a shuttle target in its justfile that runs cargo nextest with the shuttle feature against the parallel test.
What licence does salsa-rs/salsa use?
The repository contains LICENSE-APACHE and LICENSE-MIT, and the metadata lists Apache-2.0. That dual-licence layout is the common Rust convention; how it applies to your redistribution is a matter for your own review.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/salsa-rs-salsa)