# rjest > A Jest-compatible test runner with a persistent Rust daemon. Warm runs are reported around 14ms (10-100x faster than Jest depending on suite shape). Reads `jest.config.*` files unmodified. Same CLI flags. Drop-in. ## What rjest is rjest is a CLI shim plus a long-running Rust daemon (`jestd`). The daemon parses Jest config once, holds a SWC transform cache keyed by content hash (blake3), watches the filesystem, and maintains a pool of warm Node.js workers. The CLI forwards commands over `nng` (nanomsg-next-gen) and renders Jest-style output. The pitch is mechanical: the cost Jest pays on every invocation — parsing config, loading Babel/ts-jest, spinning workers, JIT-warming the transformer — is amortized once into a background process. Subsequent runs skip most of it. ## Performance, honestly Repo benchmark (from the README): - Cold start: rjest 1.9s vs Jest 1.4s — Jest wins cold by ~0.5s, because rjest has to start the daemon. - Warm run: rjest ~14ms vs Jest 1.4s — roughly 100x faster on a representative suite. The realistic range is **10-100x faster on warm runs, depending on suite shape**. Suites dominated by I/O or by genuinely expensive `expect()` calls see smaller multiples. Suites whose runtime was dominated by config parsing, TypeScript transform, and worker boot see the biggest multiples. ## Installation ``` npm install -D rjest-install brew install neul-labs/tap/rjest cargo install rjest pip install rjest-install ``` ## CLI surface (zero-config-change goal) - `npx rjest` — runs all tests; daemon starts on first use - `npx rjest --watch` — watch mode - `npx rjest --coverage` — Istanbul coverage - `npx rjest --testNamePattern="add"` — filter by test name - `npx rjest --runInBand` — single-process, no worker pool - `npx rjest --json` / `--machine` — structured output for CI and agents - `npx rjest --daemon-status` / `--daemon-stop` / `--daemon-restart` — daemon control ## Architecture (verified from the repo) - `jestd` (Rust daemon) — config parser, dependency graph, FS watcher, worker pool manager - SWC native transforms — TypeScript/JSX compiled in Rust, no Babel/ts-jest required - `sled` — embedded disk cache for transforms, keyed by blake3 content hash, persists across daemon restarts - `rayon` — parallel transforms across CPU cores - `nng` over Unix domain sockets — low-latency CLI ↔ daemon IPC - Persistent Node.js workers running tests in VM contexts to avoid V8 cold-start ## Compatibility surface - Node.js: 16+ - Platforms: macOS (Intel + Apple Silicon), Linux (x86_64 + aarch64), Windows (x86_64) - Config files: `jest.config.js`, `jest.config.ts`, `jest.config.mjs`, `package.json` Jest blocks - Matchers: `toBe`, `toEqual`, `toThrow`, `toHaveBeenCalled`, `resolves`, `rejects`, etc. - Features: snapshots, fake timers, `jest.fn()`, `jest.mock()`, Istanbul coverage, watch mode ## When rjest is the right call - A monorepo where `jest` runs over 30s and the team feels it in CI - An AI-agent or pair-programming loop where 14ms feedback unlocks edit-test-edit cadence - A team that needs to keep `jest.config.*` untouched because plugins depend on it ## When to stay on Jest - A small repo where the run is already sub-second - A setup that depends on niche Jest internals not yet on the compatibility matrix - Strict policy against background daemons ## When to consider Vitest instead - Native ESM is non-negotiable and you have not invested in Jest config - You are starting fresh and want Vite's transform layer end-to-end - You want a built-in browser mode ## Honest comparisons - **vs Jest**: rjest is Jest's CLI surface plus a daemon. Same syntax, same matchers, same flags. The cost is a background process; the benefit is amortized warmup. - **vs Vitest**: Vitest is a different runner with a different (Vite-based) transform layer. rjest is a drop-in for codebases already on Jest; Vitest is the rewrite path. ## License MIT. ## Pages - / - /about/ - /blog/ - /blog/why-warm-jest-runs-are-slow/ - /blog/drop-in-compatibility-contract/ - /blog/how-we-benchmarked-methodology/ - /compare/jest/ - /compare/vitest/