Skip to content

Commit 873ffa8

Browse files
authored
Merge pull request #1839 from counterfact/copilot/refine-readme-content
Refine the README: concise two-paragraph intro + ten variants
2 parents 258de47 + b26617e commit 873ffa8

File tree

12 files changed

+379
-159
lines changed

12 files changed

+379
-159
lines changed

.changeset/refine-readme.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"counterfact": patch
3+
---
4+
5+
Replaced the five-minute walkthrough README with a concise, confident two-paragraph introduction. Added ten README variants under `docs/readme-variants/` for the team to review and choose from.

README.md

Lines changed: 4 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -4,174 +4,19 @@
44

55
<br>
66

7-
**Your backend isn't ready. Your frontend can't wait.**
8-
9-
**Counterfact turns your OpenAPI spec into a live, stateful API you can program in TypeScript.**
10-
11-
<br>
12-
137
![MIT License](https://img.shields.io/badge/license-MIT-blue) [![TypeScript](./typescript-badge.png)](https://github.com/ellerbrock/typescript-badges/) [![Coverage Status](https://coveralls.io/repos/github/pmcelhaney/counterfact/badge.svg)](https://coveralls.io/github/pmcelhaney/counterfact)
148

159
</div>
1610

17-
This is a five-minute walkthrough. By the end, you’ll have a **stateful, type-safe, hot-reloading API simulator** running locally—and you’ll understand why it’s different from traditional mock servers.
18-
19-
Built for frontend developers, test engineers, and AI agents that need a predictable API to work against.
11+
You've used mock servers. You know where they stop being useful: static responses, no shared state, no way to inject a failure mid-run, no control without restarting. Counterfact picks up where they leave off.
2012

21-
22-
23-
## Minute 1 — Start the server
13+
Point it at an OpenAPI spec and it generates TypeScript handlers for every endpoint—type-safe, hot-reloading, sharing state across routes. A built-in REPL gives you a live control surface: seed data, trigger error conditions, proxy individual routes to a real backend, all on a running server. Whether you're a frontend developer waiting on a backend, a test engineer who needs clean reproducible state, or an AI agent that needs a stable API to work against, Counterfact is the simulator that doesn't plateau.
2414

2515
```sh
2616
npx counterfact@latest https://petstore3.swagger.io/api/v3/openapi.json api
2717
```
2818

29-
> **Requires Node ≥ 22.0.0**
30-
31-
That’s it.
32-
33-
Counterfact reads your spec, generates a TypeScript handler for every endpoint, and starts a server at `http://localhost:3100`.
34-
35-
Open `http://localhost:3100/counterfact/swagger/`.
36-
37-
Every endpoint is already live, returning random, schema-valid responses. No code written yet.
38-
39-
40-
41-
## Minute 2 — Make a route return real data
42-
43-
Open the generated file for `GET /pet/{petId}`:
44-
45-
```ts
46-
import type { HTTP_GET } from "../../types/paths/pet/{petId}.types.js";
47-
48-
export const GET: HTTP_GET = ($) => $.response[200].random();
49-
```
50-
51-
Replace `.random()` with your own logic:
52-
53-
```ts
54-
export const GET: HTTP_GET = ($) => {
55-
if ($.path.petId === 99) {
56-
return $.response[404].text("Pet not found");
57-
}
58-
return $.response[200].json({
59-
id: $.path.petId,
60-
name: "Fluffy",
61-
status: "available",
62-
photoUrls: []
63-
});
64-
};
65-
```
66-
67-
Save the file. The server reloads instantly—no restart, no lost state.
68-
69-
TypeScript enforces the contract. If your response doesn’t match the spec, you’ll know before you make the request.
70-
71-
## Minute 3 — Add state that survives across requests
72-
73-
Real APIs have memory. Yours should too.
74-
75-
Create `api/routes/_.context.ts`:
76-
77-
```ts
78-
import type { Pet } from "../types/components/pet.types.js";
79-
80-
export class Context {
81-
private pets = new Map<number, Pet>();
82-
private nextId = 1;
83-
84-
add(data: Omit<Pet, "id">): Pet {
85-
const pet = { ...data, id: this.nextId++ };
86-
this.pets.set(pet.id, pet);
87-
return pet;
88-
}
89-
90-
get(id: number): Pet | undefined { return this.pets.get(id); }
91-
list(): Pet[] { return [...this.pets.values()]; }
92-
remove(id: number): void { this.pets.delete(id); }
93-
}
94-
```
95-
96-
Use it in your routes:
97-
98-
```ts
99-
export const GET: HTTP_GET = ($) => $.response[200].json($.context.list());
100-
export const POST: HTTP_POST = ($) => $.response[200].json($.context.add($.body));
101-
```
102-
103-
Now your API behaves like a real system:
104-
- POST creates data
105-
- GET returns it
106-
- DELETE removes it
107-
108-
State survives hot reloads. Restarting resets everything—perfect for clean test runs.
109-
110-
111-
112-
## Minute 4 — Control the system at runtime (REPL)
113-
114-
This is where Counterfact becomes more than a mock.
115-
116-
The built-in REPL lets you inspect and control the system while it’s running.
117-
118-
Seed data:
119-
120-
```
121-
⬣> context.add({ name: "Fluffy", status: "available", photoUrls: [] })
122-
⬣> context.add({ name: "Rex", status: "pending", photoUrls: [] })
123-
```
124-
125-
Make requests:
126-
127-
```
128-
⬣> client.get("/pet/1")
129-
```
130-
131-
Simulate failures instantly:
132-
133-
```
134-
⬣> context.rateLimitExceeded = true
135-
⬣> client.get("/pet/1")
136-
{ status: 429, body: "Too Many Requests" }
137-
```
138-
139-
No HTTP scripts. No restarts. Just direct control.
140-
141-
142-
143-
## Minute 5 — Proxy to the real backend
144-
145-
When parts of your backend are ready, forward them through.
146-
147-
Everything else stays simulated.
148-
149-
```sh
150-
npx counterfact@latest openapi.yaml api --proxy-url https://api.example.com
151-
```
152-
153-
Toggle paths live:
154-
155-
```
156-
⬣> .proxy on /payments
157-
⬣> .proxy on /auth
158-
⬣> .proxy off
159-
```
160-
161-
162-
163-
## What you just built
164-
165-
In five minutes, you turned a static spec into a working system:
166-
167-
- **Schema-valid responses** from the moment it starts
168-
- **Type-safe handlers** generated from your spec
169-
- **Shared state** across all routes
170-
- **Hot reloading** without losing that state
171-
- A **live control surface (REPL)** for runtime behavior
172-
- **Selective proxying** to real services
173-
174-
19+
> Requires Node ≥ 22.0.0
17520
17621
## Go deeper
17722

@@ -189,4 +34,4 @@ In five minutes, you turned a static spec into a working system:
18934

19035
[Changelog](./CHANGELOG.md) · [Contributing](./CONTRIBUTING.md)
19136

192-
</div>
37+
</div>

docs/readme-variants/variant-1.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<div align="center" markdown="1">
2+
3+
<img src="../../counterfact.svg" alt="Counterfact" border=0>
4+
5+
<br>
6+
7+
![MIT License](https://img.shields.io/badge/license-MIT-blue) [![TypeScript](../../typescript-badge.png)](https://github.com/ellerbrock/typescript-badges/) [![Coverage Status](https://coveralls.io/repos/github/pmcelhaney/counterfact/badge.svg)](https://coveralls.io/github/pmcelhaney/counterfact)
8+
9+
</div>
10+
11+
Counterfact turns an OpenAPI spec into a live, stateful API server you can program in TypeScript. Point it at a spec and every endpoint is immediately live—returning schema-valid responses, sharing state across routes, and hot-reloading when you edit a handler.
12+
13+
That's where traditional mock servers stop. Counterfact keeps going. A built-in REPL lets you inspect and manipulate the running server: seed data, trigger failure modes, flip a proxy on or off—without restarting. It's a direct control surface for a running API. It works for frontend developers who can't wait on a backend, for test engineers who need reproducible states, and for AI coding agents that need a programmable, predictable sandbox to iterate in.
14+
15+
```sh
16+
npx counterfact@latest https://petstore3.swagger.io/api/v3/openapi.json api
17+
```
18+
19+
> Requires Node ≥ 22.0.0
20+
21+
## Go deeper
22+
23+
| | |
24+
|---|---|
25+
| [Getting started](../getting-started.md) | Detailed walkthrough with state, REPL, and proxy |
26+
| [Usage](../usage.md) | Feature index: routes, context, REPL, proxy, middleware, and more |
27+
| [Patterns](../patterns/index.md) | Failures, latency, AI sandboxes, integration tests |
28+
| [Reference](../reference.md) | `$` API, CLI flags, architecture |
29+
| [How it compares](../comparison.md) | json-server, WireMock, Prism, Microcks, MSW |
30+
| [FAQ](../faq.md) | State, types, regeneration |
31+
| [Petstore example](https://github.com/counterfact/example-petstore) | Full working example |
32+
33+
<div align="center" markdown="1">
34+
35+
[Changelog](../../CHANGELOG.md) · [Contributing](../../CONTRIBUTING.md)
36+
37+
</div>

docs/readme-variants/variant-10.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<div align="center" markdown="1">
2+
3+
<img src="../../counterfact.svg" alt="Counterfact" border=0>
4+
5+
<br>
6+
7+
![MIT License](https://img.shields.io/badge/license-MIT-blue) [![TypeScript](../../typescript-badge.png)](https://github.com/ellerbrock/typescript-badges/) [![Coverage Status](https://coveralls.io/repos/github/pmcelhaney/counterfact/badge.svg)](https://coveralls.io/github/pmcelhaney/counterfact)
8+
9+
</div>
10+
11+
The shift toward AI-assisted development changes what a mock server needs to be. Agents iterate fast, depend on state carrying over between requests, and need to simulate failures and edge cases on demand. Static mocks—fixed responses, no memory, no runtime control—aren't enough anymore.
12+
13+
Counterfact is a programmable API simulator built for this moment. It reads an OpenAPI spec and starts a stateful TypeScript server in one command. A built-in REPL lets you—or an agent—control the running system: seed data, trigger failures, proxy individual routes to a real backend. The handlers it generates are type-safe, hot-reloading, and share state across routes. It works equally well for human developers who can't wait on a backend and for AI agents that need a reliable sandbox to reason about.
14+
15+
```sh
16+
npx counterfact@latest https://petstore3.swagger.io/api/v3/openapi.json api
17+
```
18+
19+
> Requires Node ≥ 22.0.0
20+
21+
## Go deeper
22+
23+
| | |
24+
|---|---|
25+
| [Getting started](../getting-started.md) | Detailed walkthrough with state, REPL, and proxy |
26+
| [Usage](../usage.md) | Feature index: routes, context, REPL, proxy, middleware, and more |
27+
| [Patterns](../patterns/index.md) | Failures, latency, AI sandboxes, integration tests |
28+
| [Reference](../reference.md) | `$` API, CLI flags, architecture |
29+
| [How it compares](../comparison.md) | json-server, WireMock, Prism, Microcks, MSW |
30+
| [FAQ](../faq.md) | State, types, regeneration |
31+
| [Petstore example](https://github.com/counterfact/example-petstore) | Full working example |
32+
33+
<div align="center" markdown="1">
34+
35+
[Changelog](../../CHANGELOG.md) · [Contributing](../../CONTRIBUTING.md)
36+
37+
</div>

docs/readme-variants/variant-2.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<div align="center" markdown="1">
2+
3+
<img src="../../counterfact.svg" alt="Counterfact" border=0>
4+
5+
<br>
6+
7+
![MIT License](https://img.shields.io/badge/license-MIT-blue) [![TypeScript](../../typescript-badge.png)](https://github.com/ellerbrock/typescript-badges/) [![Coverage Status](https://coveralls.io/repos/github/pmcelhaney/counterfact/badge.svg)](https://coveralls.io/github/pmcelhaney/counterfact)
8+
9+
</div>
10+
11+
Mock servers have a familiar ceiling: static responses, no memory between requests, no way to control them while they're running. They're useful for simple demos but break down when you need real behavior—state that accumulates, errors that happen on demand, responses that depend on what came before.
12+
13+
Counterfact is a programmable API simulator. Give it an OpenAPI spec and it generates typed TypeScript handlers for every endpoint, starts a stateful server, and opens a REPL. From the REPL you can inspect context, seed data, and inject failure modes live—no restart, no HTTP scripts, no ceremony. When the real backend is ready, toggle a proxy endpoint by endpoint and let the rest stay simulated. It's the right tool for frontend development, integration testing, and AI coding agents that need a stable API to work against.
14+
15+
```sh
16+
npx counterfact@latest https://petstore3.swagger.io/api/v3/openapi.json api
17+
```
18+
19+
> Requires Node ≥ 22.0.0
20+
21+
## Go deeper
22+
23+
| | |
24+
|---|---|
25+
| [Getting started](../getting-started.md) | Detailed walkthrough with state, REPL, and proxy |
26+
| [Usage](../usage.md) | Feature index: routes, context, REPL, proxy, middleware, and more |
27+
| [Patterns](../patterns/index.md) | Failures, latency, AI sandboxes, integration tests |
28+
| [Reference](../reference.md) | `$` API, CLI flags, architecture |
29+
| [How it compares](../comparison.md) | json-server, WireMock, Prism, Microcks, MSW |
30+
| [FAQ](../faq.md) | State, types, regeneration |
31+
| [Petstore example](https://github.com/counterfact/example-petstore) | Full working example |
32+
33+
<div align="center" markdown="1">
34+
35+
[Changelog](../../CHANGELOG.md) · [Contributing](../../CONTRIBUTING.md)
36+
37+
</div>

docs/readme-variants/variant-3.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<div align="center" markdown="1">
2+
3+
<img src="../../counterfact.svg" alt="Counterfact" border=0>
4+
5+
<br>
6+
7+
![MIT License](https://img.shields.io/badge/license-MIT-blue) [![TypeScript](../../typescript-badge.png)](https://github.com/ellerbrock/typescript-badges/) [![Coverage Status](https://coveralls.io/repos/github/pmcelhaney/counterfact/badge.svg)](https://coveralls.io/github/pmcelhaney/counterfact)
8+
9+
</div>
10+
11+
AI coding agents need APIs that behave predictably across many requests. Static mock servers return fixed data, which isn't enough when an agent is iterating on real workflows that depend on state, error paths, or sequential side effects. Counterfact gives agents—and the developers working alongside them—a fully programmable API sandbox: stateful, type-safe, hot-reloading, and controllable at runtime.
12+
13+
Give it an OpenAPI spec and it generates TypeScript handlers for every endpoint and starts a server. The built-in REPL is the key differentiator: inspect state, seed test data, simulate failures, and toggle a proxy to a real backend—all on a live server, without restarting. It works just as well for a frontend developer who can't wait on a backend or a test engineer who needs clean, reproducible API behavior.
14+
15+
```sh
16+
npx counterfact@latest https://petstore3.swagger.io/api/v3/openapi.json api
17+
```
18+
19+
> Requires Node ≥ 22.0.0
20+
21+
## Go deeper
22+
23+
| | |
24+
|---|---|
25+
| [Getting started](../getting-started.md) | Detailed walkthrough with state, REPL, and proxy |
26+
| [Usage](../usage.md) | Feature index: routes, context, REPL, proxy, middleware, and more |
27+
| [Patterns](../patterns/index.md) | Failures, latency, AI sandboxes, integration tests |
28+
| [Reference](../reference.md) | `$` API, CLI flags, architecture |
29+
| [How it compares](../comparison.md) | json-server, WireMock, Prism, Microcks, MSW |
30+
| [FAQ](../faq.md) | State, types, regeneration |
31+
| [Petstore example](https://github.com/counterfact/example-petstore) | Full working example |
32+
33+
<div align="center" markdown="1">
34+
35+
[Changelog](../../CHANGELOG.md) · [Contributing](../../CONTRIBUTING.md)
36+
37+
</div>

docs/readme-variants/variant-4.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<div align="center" markdown="1">
2+
3+
<img src="../../counterfact.svg" alt="Counterfact" border=0>
4+
5+
<br>
6+
7+
![MIT License](https://img.shields.io/badge/license-MIT-blue) [![TypeScript](../../typescript-badge.png)](https://github.com/ellerbrock/typescript-badges/) [![Coverage Status](https://coveralls.io/repos/github/pmcelhaney/counterfact/badge.svg)](https://coveralls.io/github/pmcelhaney/counterfact)
8+
9+
</div>
10+
11+
Most mock servers are passive. You configure them, they respond, and you can't touch them while they're running. Counterfact includes a REPL—a live control surface for the running server. Inspect state. Inject data. Trigger failure modes. Toggle a proxy to a real backend. All without restarting, while your clients are connected.
12+
13+
Everything else follows from that: Counterfact reads your OpenAPI spec and generates typed TypeScript handlers for every endpoint. Handlers share state across routes. The server hot-reloads when you edit a file. Schema validation catches contract violations before you make the request. It works for frontend developers, test engineers, and AI coding agents that need a stable, programmable API sandbox.
14+
15+
```sh
16+
npx counterfact@latest https://petstore3.swagger.io/api/v3/openapi.json api
17+
```
18+
19+
> Requires Node ≥ 22.0.0
20+
21+
## Go deeper
22+
23+
| | |
24+
|---|---|
25+
| [Getting started](../getting-started.md) | Detailed walkthrough with state, REPL, and proxy |
26+
| [Usage](../usage.md) | Feature index: routes, context, REPL, proxy, middleware, and more |
27+
| [Patterns](../patterns/index.md) | Failures, latency, AI sandboxes, integration tests |
28+
| [Reference](../reference.md) | `$` API, CLI flags, architecture |
29+
| [How it compares](../comparison.md) | json-server, WireMock, Prism, Microcks, MSW |
30+
| [FAQ](../faq.md) | State, types, regeneration |
31+
| [Petstore example](https://github.com/counterfact/example-petstore) | Full working example |
32+
33+
<div align="center" markdown="1">
34+
35+
[Changelog](../../CHANGELOG.md) · [Contributing](../../CONTRIBUTING.md)
36+
37+
</div>

0 commit comments

Comments
 (0)