About
The cost is paid before the test runs.
Most of the time a Jest invocation takes has nothing to do with assertions. It is config parsing, plugin discovery, Babel or ts-jest warmup, worker boot, V8 JIT. rjest moves all of that into a background daemon and pays it once.
The thesis
Run jest --listTests on a real codebase and time it. The number is rarely zero. Now imagine paying that on every push, every save, every CI step. That is what a slow test runner is — not slow assertions, slow invocation overhead.
rjest is the answer to one question: what if you paid that overhead once per machine session, not once per command? The daemon, jestd, is a Rust process that holds the parsed config, the transform cache, the dependency graph, and a pool of warm Node.js workers. The CLI you type is a thin shim that opens a Unix domain socket and asks the daemon to run something.
What the daemon actually does
jestd does six things, and that is it:
- Parses your Jest config — js, ts, mjs, or package.json — once at startup and keeps the parsed representation in memory.
- Compiles TypeScript and JSX with SWC — natively, in Rust, with results cached by blake3 content hash. The cache lives in
sledon disk and survives daemon restarts. - Watches the file system — so the dependency graph is always current, and a warm run knows immediately which tests need to re-execute.
- Maintains a Node.js worker pool — persistent V8 processes that take a test file, run it in a VM context, and report results back. New tests get scheduled onto already-warm workers.
- Talks to the CLI over nng — nanomsg-next-gen, on a Unix domain socket. Sub-millisecond RTT.
- Renders Jest-style output — so your team's pattern-matching and CI parsers continue to work.
--jsonand--machineare also there for agents.
What this is not
rjest is not a fork of Jest. It does not re-implement Jest's matchers or globals from scratch. The compatibility contract is mechanical: read the same config files, expose the same CLI flags, produce the same output shape. Where Jest has a behavior, rjest tries to match it. Where it has not yet been verified, we say so in the compatibility matrix.
rjest is also not a different transform layer. SWC is the engine. If your code already runs through SWC in another part of your stack, the transforms will look familiar. If you depend on a Babel plugin that does something exotic, you should check the compatibility matrix carefully.
The cost of a daemon
We owe an honest accounting of the trade. A background process is a cost. It uses memory. It has a lifecycle. It can get stuck. We address each:
- Memory is bounded by the worker pool size, the transform cache size, and the config representation. The transform cache spills to disk via sled.
- Lifecycle is explicit.
rjest --daemon-statustells you if it is running.--daemon-stopshuts it down cleanly.--daemon-restartforces a cold restart. The disk cache survives all three. - Stuck is the one that matters. The CLI has a fail-safe: if the daemon does not respond on the socket within a timeout, it returns a clear error rather than hanging. You can always restart it. Bug reports about this are first-class issues.
What we mean by "100x"
The README reports a warm-run time of ~14ms versus 1.4s on the same suite — that is the 100x figure. The realistic range across suites is 10-100x. Suites dominated by I/O or by genuinely expensive assertion logic see smaller multiples. Suites whose Jest runtime was dominated by config parsing, transform, and worker boot see the largest. Our benchmarking post spells out the methodology and the caveats.
Who is building it
rjest is a project of Neullabs. It is MIT licensed. The roadmap and issue tracker are at github.com/neul-labs/rjest. Full documentation lives at rjest.docs.neullabs.com.
How to engage
The fastest way to validate rjest in your codebase is to install it alongside Jest in CI and compare results across a few hundred runs. If a test passes in Jest but not rjest, file an issue with the minimal reproducer — those are the bugs that matter most to us. If a test is faster than you expected, write about it. We collect both.