Point Counterfact at an OpenAPI spec and get a live, stateful API in seconds — with TypeScript safety, hot reload, shared state, and a programmable REPL.
Static canned responses aren't enough. No shared state. No failure injection. No control mid-run. Counterfact is an API simulator without those limits.
TypeScript handlers and typed interfaces for every endpoint, derived from your OpenAPI spec. Drift is impossible — your editor tells you before the server does.
Save a route file and the server picks it up instantly. Your in-memory state survives every reload — no lost context, no interruptions.
A live JavaScript prompt wired directly to your running server. Inspect state, inject failures, toggle proxy routes — while the server handles real traffic.
Drop a _.context.ts in any directory to share typed in-memory state. POST, GET, DELETE — all routes see the same data.
Forward some routes to a real backend while mocking everything else. Toggle individual paths live from the REPL as the real API comes online.
Restart and the system returns to a known state. Deterministic when you need repeatability. Programmable when you need realism. Optional persistence via TypeScript.
Point Counterfact at a local file or URL. It reads your entire document — endpoints, schemas, error conditions, everything.
A routes/ directory with one .ts per endpoint, plus full typed interfaces in types/. Existing route files are never overwritten.
Every endpoint is live, returning random schema-valid data by default. Swagger UI opens automatically so you can explore immediately.
Replace .random() with .json(), add state, wire up logic. Save — the server reloads instantly, state preserved.
Inspect state, inject failures, fire requests, toggle proxy routes — all from a live prompt, no file edits required.
import type { HTTP_GET, HTTP_DELETE }
from "../../types/paths/pet/{petId}.types.js";
export const GET: HTTP_GET = ($) => {
const pet = $.context.get($.path.petId);
if (!pet) {
return $.response[404].text(
`Pet ${$.path.petId} not found`
);
}
return $.response[200].json(pet);
};
export const DELETE: HTTP_DELETE = ($) => {
$.context.remove($.path.petId);
return $.response[200];
};
import type { Pet }
from "../types/components/pet.types.js";
export class Context {
private pets = new Map<number, Pet>();
private nextId = 1;
add(pet: Omit<Pet, "id">): Pet {
const id = this.nextId++;
const rec = { ...pet, id };
this.pets.set(id, rec);
return rec;
}
get(id: number) { return this.pets.get(id); }
list() { return [...this.pets.values()]; }
remove(id: number) { this.pets.delete(id); }
}
A live JavaScript prompt wired directly to your running server. The REPL exposes a context object and a client — inspect state, modify data, and fire requests all at once.
Want to test what happens when the database is empty? Clear it. Need to simulate a 500? Set it up. Proxy half the API to a real backend? One command.
Restart and everything returns to its initial state. Deterministic when you need repeatability. Programmable when you need realism.
Your team has an OpenAPI spec. The backend is two sprints out. Run Counterfact and build against a live, typed, stateful API today. No mocks to maintain. No drift.
Set up exactly the state you need from the REPL. Run your test. Restart for a clean slate. No database fixtures, no teardown scripts, no flakiness.
Agentic workflows need deterministic, scriptable APIs. Counterfact is restartable, stateless by default, and fully controllable — built for automated pipelines.
Most tools stop at response recording. Counterfact gives you a programmable simulation.
| Capability | Counterfact | Prism | WireMock | MSW |
|---|---|---|---|---|
| OpenAPI-driven generation | ✓ | ✓ | — | — |
| TypeScript type safety | ✓ | — | — | partial |
| Shared state across routes | ✓ | — | manual | manual |
| Hot reload (no restart) | ✓ | — | — | ✓ |
| Live REPL | ✓ | — | — | — |
| Proxy to real backend | ✓ | ✓ | ✓ | ✓ |
| Deterministic reset on restart | ✓ | ✓ | config | — |
| Programmable failure simulation | ✓ | — | config | manual |
No install. No configuration. Point it at any OpenAPI spec and go.
npx counterfact@latest
https://petstore3.swagger.io/api/v3/openapi.json api