rift-node
Official Node.js / TypeScript SDK for Rift — a high-performance, Mountebank-compatible HTTP/HTTPS mock server written in Rust.
One client, three transports — embedded (in-process, no Docker), spawn (a managed engine binary), and connect (any running admin endpoint) — with the same typed DSL on each: imposters, stubs, predicates, responses, response cycling, behaviors, proxy record/playback, fault injection, stateful scenarios, and request verification.
await using engine = await rift.embedded(); // or rift.connect(url) / rift.spawn()
const users = await engine.create(
imposter('users')
.record()
.stub(onGet('/api/users/1').willReturn(okJson({ id: 1, name: 'Alice' })))
.stub(onPost('/api/users').willReturn(created().latency(50), status(503)))); // cycling
await fetch(`${users.url}/api/users/1`);
await users.verify(onGet('/api/users/1'), times(1)); // throws VerificationError with a diff
.record() is what gives the imposter a journal — verify() and recorded() fail loudly on a
non-recording imposter rather than silently reporting zero calls.
Install
npm install --save-dev @rift-vs/rift
Add @rift-vs/rift-embedded when you want the in-process transport:
npm install --save-dev @rift-vs/rift @rift-vs/rift-embedded
@rift-vs/rift has zero runtime dependencies. Requires Node.js ≥ 20, ESM only.
Where to go next
| If you want to… | Read |
|---|---|
| Install it and create a first imposter | Getting Started |
| Decide between embedded, spawn and connect | Transports |
| Understand how the engine binary is found, or run air-gapped | Engine binary resolution |
| Build imposters, stubs, predicates and responses | The typed DSL |
| Assert that your system under test called the mock | Verification |
| Model multi-step, stateful flows | Scenarios & state |
| Move an existing Mountebank suite across | Mountebank compatibility |
| Look up an exact type or signature | API reference |
Two packages
| Package | Purpose |
|---|---|
@rift-vs/rift |
The SDK: typed DSL, all three transports, Mountebank-compatible create(). Zero runtime dependencies. |
@rift-vs/rift-embedded |
Optional FFI transport (koffi → librift_ffi). Installing it is what opts a project into rift.embedded(). |
Docs that don’t rot
Every runnable snippet marked <!-- docs:embed … --> on this site is generated from a compiled
file in examples/, never hand-copied. npm run docs:check extracts each marked region, normalizes
both sides, and fails naming the anchor on any mismatch — so a snippet cannot silently drift from
the API it documents. npm run typecheck:examples keeps those examples compiling against the real
source. Both run in CI on every change to this site.