Skip to content
rjest

Open source · MIT · v0 daemon shipping

Jest, but warm runs land in milliseconds.

rjest is a drop-in Jest replacement. A Rust daemon (jestd) parses your config once, holds the SWC transform cache, and keeps Node.js workers warm. The CLI is a thin shim over nng. No new config. No new syntax.

~/your-repo
$ npm install -D rjest-install
$ npx rjest --watch
 PASS  src/add.test.ts
 PASS  src/parser.test.ts
 PASS  src/queue.test.ts

Tests:       42 passed, 42 total
Time:        14ms  (daemon warm)

~14 ms

warm-run target reported in the repo benchmark

10-100×

faster on warm runs, depending on suite shape

0

changes needed to jest.config.*

What you get

A test runner shaped like a daemon

Performance

Warm runs in milliseconds

The Rust daemon parses your jest.config once, holds the SWC transform cache in memory, and keeps a pool of Node.js workers warm. The CLI just forwards over a Unix socket.

Zero config

Reads your existing jest.config

jest.config.js, jest.config.ts, jest.config.mjs, or the package.json Jest block. No new format, no schema migration. The compatibility contract is the whole point.

Drop-in

Same CLI you already type

--watch, --coverage, --runInBand, --testNamePattern, --json. If your CI script works on Jest, the diff to rjest is replacing the binary name.

Architecture

Native SWC transforms

TypeScript and JSX compiled in Rust, cached on disk by blake3 content hash via sled. No Babel, no ts-jest, no plugin chain to reload.

Tooling

--json and --machine for agents

Structured output with file paths, test names, durations, and error details. Built for CI pipelines and AI coding agents that need to parse results without scraping ANSI.

Internals

Workers stay warm across runs

Persistent Node.js processes execute tests in isolated VM contexts. V8 cold-start is paid once, not every invocation.

Operations

Daemon is observable

rjest --daemon-status, --daemon-stop, --daemon-restart. The caches persist on disk through restarts. If something feels wrong, you can audit it.

Architecture

A pipeline tuned for warm starts

01 · cli shim

rjest binary

A Rust CLI that opens a Unix domain socket to jestd, forwards args, and renders Jest-style output back.

02 · daemon

jestd

Holds the parsed Jest config, the file-system watcher, the dependency graph, and the worker pool. Survives between invocations.

03 · transforms

SWC + sled

TypeScript and JSX compiled natively. Transformed code cached on disk by blake3 hash; persists across daemon restarts.

04 · workers

Warm Node.js pool

Persistent Node processes run tests in VM contexts. V8 warmup is paid once per worker, not per invocation.

Benchmark, in context

The numbers we publish (and the ones we do not)

From the repo's README. We show cold start honestly — Jest wins there. The big multiplier is warm runs, where most of CI actually lives.

Metric rjest Jest Speedup
Cold start 1.9s 1.4s 0.7× (Jest)
Warm run ~14ms 1.4s ~100× (rjest)

Source: repo README. Real-world warm speedup ranges roughly 10-100× depending on suite shape (transform cost vs I/O vs expect() work). See our benchmarking methodology.

FAQ

What developers ask before switching

+ How much faster is rjest, really?

The published benchmark in the repo shows warm runs around 14ms versus 1.4s for Jest on the same suite — about 100x. In practice the speedup ranges from 10x to 100x depending on suite shape. Cold start is slower (1.9s vs 1.4s) because rjest has to boot the daemon; you pay that once per session.

+ Do I need to change my Jest config?

No. rjest reads jest.config.js, jest.config.ts, jest.config.mjs, or the Jest section of package.json — same as Jest. The compatibility surface includes matchers, snapshots, fake timers, jest.fn(), jest.mock(), Istanbul coverage, and watch mode.

+ Why a daemon?

Because most of the cost of a Jest run is paid before any test runs: config parsing, plugin loading, transform setup, worker boot. A daemon pays that once and amortizes it across every invocation. The CLI becomes a thin client over nng.

+ What if the daemon is stuck?

npx rjest --daemon-restart forces a cold restart. The transform cache lives on disk (sled, keyed by blake3 content hash) and survives daemon restarts, so the second cold start still benefits from cached transforms.

+ Is it production-ready?

rjest is open source under MIT. The compatibility matrix in the repo lists what is verified today. As with any new runner, start by running it alongside Jest in CI and compare. If a test passes in Jest but not rjest, file an issue — those are the contracts we want to honor.

+ Should I use rjest or Vitest?

If your codebase is on Jest and you do not want to migrate config, plugins, or transformers, rjest is the path of least resistance. If you are starting fresh and want a Vite-native transform pipeline end-to-end, Vitest is a great choice. They optimize different things.

+ What platforms are supported?

macOS (Intel and Apple Silicon), Linux (x86_64 and aarch64), and Windows (x86_64). Node.js 16 or newer.

+ How do I install it?

npm install -D rjest-install, or brew install neul-labs/tap/rjest, or cargo install rjest, or pip install rjest-install. The Node package wraps the binary so npx rjest works in any JS project.

Stop waiting on your test suite.

Install rjest in your repo, run npx rjest --watch, and watch the second run come back in milliseconds. Your jest.config stays exactly as it is.