ScriptsApr 14, 2026·3 min read

MSW — API Mocking of the Next Generation

Mock Service Worker intercepts network requests at the service worker layer, letting you mock REST and GraphQL APIs for tests and development without stubbing fetch. The same mocks work in Node, jsdom, browsers, and React Native.

TL;DR
MSW intercepts network requests at the service worker layer to mock REST and GraphQL APIs for tests and dev.
§01

What it is

Mock Service Worker (MSW) intercepts network requests at the service worker layer in the browser and at the request module level in Node.js. You define request handlers that describe how to respond to specific API calls, and MSW intercepts matching requests without modifying your application code. The same mocks work across unit tests, integration tests, Storybook, and local development.

MSW targets frontend developers who need to mock API endpoints for testing and development. It works with any HTTP client (fetch, axios, ky) and any framework (React, Vue, Angular, Svelte).

§02

How it saves time or tokens

Traditional API mocking involves stubbing fetch or axios at the module level, which breaks when you switch HTTP clients or test implementation details. MSW operates at the network level, so your application code makes real fetch calls that are intercepted transparently. This means your tests exercise the actual HTTP layer and your mocks are reusable across testing environments.

§03

How to use

  1. Install MSW: npm install msw --save-dev.
  2. Define request handlers in a handlers.ts file using http.get(), http.post(), etc.
  3. Set up the browser worker with npx msw init public/ --save or the Node server for tests.
§04

Example

// src/mocks/handlers.ts
import { http, HttpResponse } from 'msw';

export const handlers = [
  http.get('/api/user', () =>
    HttpResponse.json({ id: 1, name: 'Alice' })
  ),
  http.post('/api/login', async ({ request }) => {
    const body = await request.json();
    if (body.password === 'secret') {
      return HttpResponse.json({ token: 'abc123' });
    }
    return new HttpResponse(null, { status: 401 });
  }),
];
// src/mocks/server.ts (for Node/test environment)
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const server = setupServer(...handlers);
§05

Related on TokRepo

§06

Common pitfalls

  • Forgetting to call server.listen() in test setup and server.close() in teardown. Without these, MSW does not intercept requests.
  • Not running npx msw init public/ for browser environments. The service worker script must be in your public directory.
  • Defining handlers that are too specific (exact URL with query params) when you want to catch all variations. Use URL patterns or regex for flexible matching.

Frequently Asked Questions

Does MSW work in Node.js for testing?+

Yes. MSW provides `setupServer` from `msw/node` that intercepts outgoing HTTP requests in Node.js without a service worker. This works with Jest, Vitest, Playwright, and any Node-based test runner.

Can MSW mock GraphQL APIs?+

Yes. MSW provides `graphql.query()` and `graphql.mutation()` handlers that match GraphQL operations by name. You can return typed responses and simulate errors for specific operations.

How does MSW differ from Nock?+

Nock patches Node's http module directly and only works in Node. MSW uses service workers in the browser and module interception in Node, making the same handlers work in both environments. MSW also has a more modern API and supports GraphQL natively.

Can I use MSW in Storybook?+

Yes. MSW integrates with Storybook via the msw-storybook-addon. You define handlers per story, and the service worker intercepts API calls made by the component. This lets you demo different API states (loading, error, empty) in Storybook.

Does MSW support streaming responses?+

Yes. MSW 2.0 supports ReadableStream responses, allowing you to mock server-sent events (SSE) and chunked transfer encoding. This is useful for testing real-time features like AI chat completions or live data feeds.

Citations (3)
  • MSW GitHub— MSW intercepts requests at the service worker and Node module level
  • MSW Documentation— Supports REST and GraphQL mocking with the same handler API
  • MSW Blog— MSW 2.0 supports streaming responses and ReadableStream

Discussion

Sign in to join the discussion.
No comments yet. Be the first to share your thoughts.

Related Assets