Honest split first: nock is a battle-tested workhorse. It has been faking Node HTTP for over a decade, it can record real traffic and replay it as fixtures (nock.back โ genuinely unique), and for fast offline unit tests of Node code it's still a fine choice. This page is not going to pretend otherwise.
If your nock mock is being ignored and the request goes out for real (or dies with ENOTFOUND), check your nock major version. We verified this the week of writing (Aug 2026, Node 22):
fetch or undici at all. It patches http.ClientRequest; native fetch uses undici's own networking, so the request sails straight past your mock. In that week's npm numbers, v13 was still ~3.7M of nock's ~7.2M weekly downloads โ half the installs out there have this problem waiting.@mswjs/interceptors, and native fetch is intercepted (we ran it: stubbed response comes back). If fetch is your problem, npm install nock@latest is the honest first answer.ERR_NOCK_NO_MATCH response rather than hitting the network, and the classic rules still apply โ an interceptor is consumed after one match (the second identical request fails unless you .times(n) or .persist()), and query strings must match exactly.Upgrade done and still here? Then your actual problem is probably the deeper one:
Mockbird is the other half: a hosted mock REST API on a real URL. Define resources (or pick a preset, or import an OpenAPI spec / db.json / CSV / Postman collection), get realistic seeded data and full stateful CRUD โ reachable from Node, a browser, curl, a phone, another service, CI, or a teammate. No interceptor code, no signup.
# one curl, no signup โ a whole seeded e-commerce backend
curl -X POST https://mockbird.mockbird.workers.dev/api/projects \
-H 'content-type: application/json' -d '{"name":"shop","preset":"ecommerce"}'
# โ {"id":"abc123","adminKey":"KEY", ...} โ save both
curl https://mockbird.mockbird.workers.dev/m/abc123/products?limit=3
# โ 3 seeded products, CORS on, writes persist
Prefer clicking? This link creates the same project in your browser โ no account. Have an OpenAPI spec? Paste it at /app#import and get a live seeded mock of your actual API shape.
| nock | Mockbird | Notes |
|---|---|---|
nock(host).get('/products').reply(200, data) | a products resource | list/get/create/update/delete generated, plus filtering, sorting, pagination, relations |
| Hand-rolled reply data | seeded realistic records | faker-style names/emails/prices/dates; or import your exact records from db.json/CSV |
.reply(500) / .replyWithError(โฆ) | ?mock_status=500 on any URL | no interceptor edit โ error/loading states guide; ?mock_chaos=0.3 fails a random fraction for retry tests |
.delay(2000) / .delayConnection(โฆ) | ?mock_delay=2000 | plus ?mock_jitter=100-1500 random latency โ real timeouts actually fire |
.times(n) / .persist() | not needed | a hosted endpoint answers every request; there's no consumed-interceptor gotcha |
| Strict query/body matching misses | not needed | any query composes: filters, ?select=, sort, pagination โ no "why didn't it match" |
scope.done() / pendingMocks() | request inspector | last 50 requests: method, path, query, headers, body โ assert what was actually sent |
nock.back record/replay fixtures | closest: import your real spec/data | honest note: we don't record live traffic from your real API โ nock wins here |
nock.cleanAll() between tests | snapshot pinning | save named data states; each parallel test pins one via X-Mockbird-Snapshot โ no reset races |
disableNetConnect() | n/a | point your base URL at the mock and nothing else gets called |
# seeded data with field projection
curl 'https://mockbird.mockbird.workers.dev/m/demo/products?limit=2&select=name,price'
# the states you'd write interceptors for โ as query params
curl -i 'https://mockbird.mockbird.workers.dev/m/demo/products?mock_status=503'
curl 'https://mockbird.mockbird.workers.dev/m/demo/products/1?mock_delay=2000'
# stateful: the write persists
curl -X POST https://mockbird.mockbird.workers.dev/m/demo/products \
-H 'content-type: application/json' -d '{"name":"proof","price":9.99}'
# โ returns {"id":31,โฆ} โ and GET /m/demo/products/31 now works
All against the shared demo project (resets daily).
?mock_delay=3000 makes a 1s AbortSignal.timeout actually fire, and ?mock_chaos=0.5 gives your backoff real 5xx storms to absorb โ recipes in the Node.js guide.GET /m/<project>/msw.js returns an MSW v2 handlers module with your project's current data baked in โ shape data in the dashboard, then run offline unit tests from generated code. No lock-in in either direction.| nock | Mockbird | |
|---|---|---|
| What it is | free OSS library (Node) | free hosted service |
| Reachable from | your Node process only | anything with HTTP: browser, curl, Postman, mobile, backend, CI, agents |
| Native fetch/undici | v14+ yes; v13 (half the installs) no | it's a real URL โ every client works by definition |
| Setup | write + maintain interceptors | one curl or one click; no code |
| Mock data | you write it (or record with nock.back) | seeded realistic data, or import your own |
| Stateful CRUD | DIY | default โ writes persist |
| Error/latency simulation | per-interceptor code | ?mock_status / ?mock_delay / ?mock_chaos / ?mock_jitter on any URL |
| Record/replay real traffic | yes โ nock.back, unique | no |
| Works offline | yes | no โ it's a real network call |
| Latency | zero (in-process) | real network latency |
| Request assertions | scope.done(), precise | request inspector (last 50, with headers/body) |
| Per-test isolation | cleanAll() + discipline | snapshot pinning + restore recipes |
| Request cap | none | 10,000/project/day |
Written by the Mockbird maker โ bias disclosed. Where nock genuinely wins: recording real API traffic and replaying it offline has no equivalent here; in-process interception means zero latency, zero network flakiness, tests that run on a plane; scope.done() assertions are more precise than any log-based check; and a reply function is arbitrary JavaScript. For offline Node unit tests, keep nock โ on v14+. When the thing you need is a URL โ for a browser, a prototype, a teammate, a mobile client, or CI hitting a deployed build โ that's us.
Full API reference in the docs. More guides: mock API for Node.js ยท mock APIs in Vitest ยท MSW alternative ยท Mirage JS alternative ยท free mock API tools compared ยท deterministic test data ยท testing loading & error states. Create your API โ