Captures real API responses while your Playwright suite runs locally,
then replays them byte-for-byte on CI. No backend, no network, no
hand-written mocks to maintain.
MIT · TypeScript · works with Next.js SSR, SPAs & Chrome extensions ·
WebSocket support
npx playwright test
REC · MODE=record · local run
your appproxyreal API
⤓
saved e2e/recordings/todos.GET.mock.json
▶
REPLAY · MODE=replay · CI
your appproxydisk
✓
200 OK · 3 ms · zero network
See it record, then replay
One Playwright run records real responses to disk; flip to replay and the same
suite passes with the backend off — no network.
Two recorders, one proxy
Requests originate in two places, so there are two recording mechanisms.
Use either — or both together. Both record once and replay from disk, so
CI runs with the backend off and no hand-written mocks.
Proxy
.mock.json
Next.js SSR → proxy → real API
Sits between your server and the API. Records server-side requests —
SSR fetches, route handlers, anything your backend-for-frontend calls.
For full-stack apps where the server calls the API.
The mocking tools are good at different jobs. The combination below — recording
real traffic across SSR, browser, and WebSockets, with no hand-written mocks — is
the gap the others leave open.
Feature comparison of test-proxy-recorder against Playwright routeFromHAR, MSW,
Polly.js, playwright-network-cache, and Mocky Balboa.
Feature
test-proxy-recorder
Playwright routeFromHAR
MSW
Polly.js
playwright-network-cache
Mocky Balboa
Record real traffic
✓ Yes
✓ Yes
✕ No
✓ Yes
✓ Yes
✕ No
Server-side (SSR)
✓ Yes
✕ No
✓ Yes
~ Partial
✕ No
✓ Yes
Browser-side
✓ Yes
✓ Yes
✓ Yes
✓ Yes
✓ Yes
✓ Yes
WebSocket
✓ Yes
✕ No
✓ Yes
✕ No
✕ No
✕ No
Playwright-native
✓ Yes
✓ Yes
✕ No
✕ No
✓ Yes
✓ Yes
Maintained
✓ Yes
✓ Yes
✓ Yes
✕ No
✓ Yes
✓ Yes
~ Polly.js intercepts Node HTTP, so
SSR mocking is possible inside the app process, but not as part of a Playwright run.
MSW and Mocky Balboa replay real responses too — but you hand-write the mocks.
When to reach for something else is covered in the docs.
Works with your real auth provider
Log in through Cognito, Auth0, Clerk, or WorkOS — for real, on every run.
Only your app's API is recorded; auth stays live, your data goes offline.
// e2e/auth.setup.ts — log in for real, once. Never recorded.
Scaffold everything with one command, point your API at the proxy, then
record and commit. Browser-only app? init skips the SSR
step for you.
Fastest path: hand it to your AI agent
Copy this, swap in your backend URL, and paste it into Claude Code,
Cursor, or any coding agent — it runs init and finishes
the wiring from the prompt init prints.
Set up test-proxy-recorder for end-to-end tests in this project, then follow the
instructions that `init` prints. Run these commands:
npx @tanstack/intent@latest install
npm install --save-dev test-proxy-recorder
Then run init, passing this project's backend API base URL as the target — find
it yourself from the app's env/config (the URL the app calls in dev); don't
Then complete the app-specific steps init prints: point the app's API base URL at
the proxy in dev/test only, tag server-side fetches (Next.js), add a smoke test,
and verify record → replay.
Or wire it up by hand:
Install & scaffold
init writes the proxy config, a Playwright fixture, a
global teardown, package.json scripts, and (on Next.js)
wires SSR fetch tagging into your root layout — non-destructively.
Terminal window
npminstall--save-devtest-proxy-recorder
# http://localhost:3002 is your API endpoint; 8100 is the proxy. Flags are optional.
The one thing init can't guess: which env var holds your
API base URL. Point it at the proxy when the recorder is enabled, at
the real backend otherwise — the proxy never runs in production.
// Point your app at the proxy when the recorder is enabled, at the real backend otherwise.
// The proxy never runs in production — TEST_PROXY_RECORDER_ENABLED is set only for e2e.
registerProxyFetch(); // no-op in production unless TEST_PROXY_RECORDER_ENABLED=true
Record, commit, replay
Set MODE = 'record', run once against the real API, then
flip to 'replay' and commit. Recordings live in git —
that's what makes CI deterministic. Don't gitignore them.
If it saved you an afternoon, a star takes one second — it's how the next
person finds it, and it tells a solo maintainer to keep building.
Hit a snag or have an idea? Open an issue or
join Discord.