- Introduction
- Getting started
- Philosophy
- Comparison
- Limitations
- Debugging runbook
- FAQ
- Basics
- Concepts
- Network behavior
- Integrations
- API
- CLI
- Best practices
- Recipes
- Cookies
- Query parameters
- Response patching
- Polling
- Streaming
- Network errors
- File uploads
- Responding with binary
- Custom worker script location
- Global response delay
- GraphQL query batching
- Higher-order resolver
- Keeping mocks in sync
- Merging Service Workers
- Mock GraphQL schema
- Remote Request Interception
- Using CDN
- Using custom "homepage" property
- Using local HTTPS
Getting started
Three steps to get started with Mock Service Worker.
Developers use MSW for many things: to mock APIs in testing, to debug network while developing, to present their work across teams, to monitor the outgoing traffic, etc. Writing a single tutorial that would suit all those use cases is rather difficult. There’s good news, however. Working with MSW follows the same flow, no matter how and where you decide to use it.
Below, you can find a complete, barebones tutorial that integrates MSW in a Node.js application. Please note that this tutorial is intended as a working reference, and you are encouraged to follow the additional links in each of the sections below to achieve the integration you want.
Step 1: Install
Install MSW as a dependency by running the following command in your project:
npm install msw@latest --save-dev
If you need to, you can also install MSW from a CDN.
Step 2: Describe
Next, you describe the network using Request handlers (e.g. http.get()
, graphql.query()
). A request handler is responsible for intercepting a request and handling its response, which can be a mocked response, a combination of the real response and a mock, or nothing, if you only want to monitor the traffic without affecting it.
In this tutorial, let’s define a single HTTP request handler for a GET https://example.com/user
request and respond to it with a mocked JSON response.
// src/mocks/handlers.js
import { http, HttpResponse } from 'msw'
export const handlers = [
// Intercept "GET https://example.com/user" requests...
http.get('https://example.com/user', () => {
// ...and respond to them using this JSON response.
return HttpResponse.json({
id: 'c7b3d8e0-5e0b-4b0f-8b3a-3b9f4b3d3b3d',
firstName: 'John',
lastName: 'Maverick',
})
}),
]
Start small with a single
handlers.js
module that contains the entire network description. With time, you can restructure your handlers and learn how to override them on runtime.
You can describe different APIs, like REST or GraphQL, including at the same time in the same handlers
array. Learn more about describing server APIs with MSW:
Describing REST API
Learn about describing RESTful APIs.
Describing GraphQL API
Learn about describing GraphQL APIs.
You can make the most out of MSW by annotating your request handlers using TypeScript. This is particularly handy when you have type definitions generated by your actual API, be it an OpenAPI document or GraphQL Code Generator.
Step 3: Integrate
MSW integrates with any frameworks, request libraries, and other tools because it applies itself on the environment level, which means you only have to decide whether you want to use it in the browser or in a Node.js process (or both). You still (re)use the same request handlers regardless of the environment you are in.
For this tutorial, let’s integrate MSW into a plain Node.js process by creating a Node.js integration module called node.js
:
// src/mocks/node.js
import { setupServer } from 'msw/node'
import { handlers } from './handlers'
export const server = setupServer(...handlers)
We recommend creating environment-dependent integration modules, like
node.js
andbrowser.js
, so you can reuse the same integrations across different tools. Any tooling in JavaScript runs either in the browser (actual browsers, Playwright, Cypress, Storybook) or in Node.js (Vitest, Jest, React Native). Pull in the right integration based on your tool’s environment, and you are all set.
The node.js
integration module we’ve created configures MSW to run in any Node.js process but doesn’t actually start it just yet. To start the request interception, you need to call server.listen()
in your Node.js process:
// src/index.js
import { server } from './mocks/node'
server.listen()
// This is a simple Node.js application that
// does a network request and prints the response.
async function app() {
const response = await fetch('https://example.com/user')
const user = await response.json()
console.log(user)
}
app()
You can also start MSW conditionally, based on
process.env.NODE_ENV
or any other criteria.
Running the application will now print the mocked response without actually making a network request:
node ./src/index.js
{
id: 'c7b3d8e0-5e0b-4b0f-8b3a-3b9f4b3d3b3d',
firstName: 'John',
lastName: 'Maverick'
}
Learn more about integrating MSW into different environments:
Browser
Integrate MSW in a browser environment, such as a React application or Storybook.
Node.js
Integrate MSW in Node.js, such as an Express application or a test runner.
React Native
Integrate MSW in a React Native application.
Examples
In the repository below, you can find the functional, complete, and minimalistic examples of how to use Mock Service Worker with tools like Jest, Vitest, Cypress, Playwright, Angular, Svelte, Remix, and others. Use them as a reference whenever integrating MSW with those tools.
Usage examples
Examples of Mock Service Worker usage with various frameworks and libraries.
Turn each usage example into a reproduction repository if you encounter an issue!
Need help?
Starting with a new tool can be difficult but you don’t have go through that alone. Whenever you encounter an issue, the best place to go is our Debugging runbook:
Debugging runbook
Steps to debug common issues with the library.
We are always happy to help you with any questions you might have. There are multiple ways you can reach out to us or other community members to get help:
And remember, there is always a person who’s one problem behind you. Be kind and offer help when you can.