MSW (Mock Service Worker)
API mocking that intercepts requests at the network level — same handlers in the browser and Node.
Pricing
Free / Open source
Type
Automation
Languages
JavaScript, TypeScript
// VERDICT
Reach for MSW when you want JS/TS frontend or Node tests to mock at the network boundary with no separate mock server to run. Skip it when your consumers aren't JS or you need a standalone server other stacks can hit.
Best for
Intercepting requests at the network layer (Service Worker in the browser, or Node) so frontend and Node tests run against realistic mocks without a separate server.
Avoid when
You're not in a JS/TS environment, or you need a standalone mock server for non-JS consumers.
CI/CD fit
Jest · Vitest · Playwright · GitHub Actions · npm
Languages
JavaScript · TypeScript
Team fit
Frontend teams · JavaScript/TypeScript teams · React/Vue/Node teams
Setup
Maintenance
Learning
Licence
// BEST FOR
- Mocking at the network layer, so app code makes real fetch/XHR calls
- One set of handlers reused across unit, integration and E2E tests
- Frontend tests (Jest/Vitest) and browser tests (Playwright) without a server
- Realistic mocking that doesn't couple tests to fetch-library internals
- Development-time mocking in the browser via a Service Worker
- Node and browser support from the same handler definitions
// AVOID WHEN
- Your stack or consumers aren't JavaScript/Node
- You need a standalone server that non-JS systems can call
- You want a no-code GUI to define mocks
- Backend/JVM integration tests need the mock (WireMock/MockServer)
- You're validating a real API rather than mocking one
- Consumer/provider contract testing is the goal (Pact)
// QUICK START
npm install --save-dev msw
# define handlers, then setupServer(...handlers) (Node) or worker.start() (browser)// ALTERNATIVES TO CONSIDER
| Tool | Choose it when |
|---|---|
| WireMock | You need a JVM-side standalone stubbing server. |
| MockServer | You want a standalone mock/proxy server non-JS systems can hit. |
| JSON Server | You want a zero-config fake REST API from a JSON file. |
// FEATURES
- Service Worker interception in the browser
- Node interception via msw/node for unit and integration tests
- Same handlers across browser, Vitest/Jest, and Playwright/Cypress
- REST and GraphQL request matching
- TypeScript-first API
- Storybook integration for component-level mocking
// PROS
- Single source of truth for mocks across all test layers
- No fake server to spin up — runs in-process
- Excellent TypeScript ergonomics
- Fast and accurate request matching
// CONS
- Service Worker constraints (HTTPS in dev, scope rules)
- Setup steeper than a plain stub library
- Browser support depends on Service Worker availability
// EXAMPLE QA WORKFLOW
Install MSW and write request handlers
Start it in Node (setupServer) or the browser (Service Worker)
Reuse the same handlers across unit, integration and E2E tests
Reset handlers between tests for isolation
Keep handlers aligned with the real API's shapes
Run in the normal JS test step in CI
// RELATED QA.CODES RESOURCES
Cheat sheets
Glossary
Interview