Comparison

Mock Service Worker comparison with similar tools.

Choosing the right tool for the job is crucial. We tried our best to provide a comprehensive and unbiased comparison between Mock Service Worker and other open-source API mocking libraries below.

Comparison criteria

Any good comparison begins with a clearly defined set of criteria. Here are the criteria we used when comparing MSW to alternatives (written from a developer’s perspective):

  • Supported API types. What kinds of API can I mock with the library?
  • Environment. In which environments can I use the library?
  • Implementation. How does the library implement request interception?
  • Integration. How much effort it takes to integrate it into my project?
  • Definition. How do I define mocks?

Nock

Nock is an HTTP server mocking and expectations library for Node.js.

Nock is a great library for combining API mocking and assertions in Node.js. While Mock Service Worker doesn’t come with a built-in assertion capabilities, it allows you to seamlessly reuse the same mocks across browser and Node.js, as well as providing first-class GraphQL support and standard-based request/response handling.

API support

API typeNockMock Service Worker
REST API
GraphQL API
WebSocket API

Supported environment

EnvironmentNockMock Service Worker
Node.js
Browser

Integration

NockMock Service Worker
Does not require any changes to the code.Does not require any changes to the code.
Requires additional adapters to intercept specific request clients (e.g. axios)Works with any request client without additional configuration.

Definition

Nock

Nock uses method chaining to intercept requests and declare mocked responses:

nock('https://api.example.com').get('/user').reply(200, { id: 1, name: 'John' })

Mock Service Worker

MSW models its interception API after server-side routing and handles requests and responses according to the Fetch API specification, using the same classes you would use normally in JavaScript:

http.get('https://api.example.com/user', async ({ request }) => {
  const payload = await request.json()
  return HttpResponse.json({ id: 1, name: 'John' })
})

JSON Server

JSON Server allows you to create an actual HTTP server based on a JSON file.

JSON Server is an actual HTTP server that utilizes abstract response definition format. This means a server you have to run and maintain. Mock Service Worker doesn’t spawn any servers, so its initialization cost is free. Mock Service Worker also allows you to have a more error-proof mock definitions by using languages like TypeScript and generating mocks out of the actual backend implementation.

API support

API typeJSON ServerMock Service Worker
REST API
GraphQL API
WebSocket API

Supported environment

EnvironmentJSON ServerMock Service Worker
Node.js
Browser1

1—JSON Server doesn’t actually run in the browser. Since it’s a standalone server, it can be requested from anywhere in your system.

Integration

JSON ServerMock Service Worker
Requires to change the code to request resources from the mocked server.Does not require any changes to the code.
Works with any request client without additional configuration.Works with any request client without additional configuration.

Definition

JSON Server

JSON Server uses a resource-first routes format that implicitly generates request paths and describes mocked responses.

{
  "posts": [
    { "id": 1, "title": "json-server" },
    { "id": 2, "title": "mock-service-worker" }
  ]
}

This will automatically generated server-side routes like GET /posts and DELETE /posts/:index based on the described resources. The nature of such routes is static and requires additional abstractions to achieve more complex network behaviors.

Mock Service Worker

MSW models its interception API after server-side routing and handles requests and responses according to the Fetch API specification, using the same classes you would use normally in JavaScript:

http.get('/posts', () => {
  return HttpResponse.json([
    { id: 1, title: 'json-server' },
    { id: 2, title: 'mock-service-worker' },
  ])
})

With MSW, you have to explicitly define server-side operations like http.get('/posts') or http.delete('/posts/:index'). MSW prioritized explicitness, taking advantage of programmatic request resolution, allowing for more complex network behaviors.

Mirage

Mirage is an API mocking library that lets you build, test and share a complete working JavaScript application without having to rely on any backend services.

Mirage is centered around data modeling to emulate more complex server behaviors. Mock Service Worker doesn’t come with a built-in data modeling capabilities and instead exposes them in a separate package called @mswjs/data. This way you can bring modeling to the table once you need it.

API support

API typeMirageMock Service Worker
REST API
GraphQL API
WebSocket API

Supported environments

EnvironmentMirageMock Service Worker
Node.js
Browser

Implementation

EnvironmentMirageMock Service Worker
BrowserMonkey-patches fetch and XMLHttpRequest (uses pretender).Uses a Service Worker to intercept requests on the browser level.

Integration

MirageMock Service Worker
Does not require any changes to the code.Does not require any changes to the code.
Works with any request client without additional configuration.Works with any request client without additional configuration.

Definition

Mirage

Mirage uses route handlers format to define server-like routes and mocked responses.

createServer({
  routes() {
    this.get('/movies', () => {
      return ['Interstellar', 'Inception', 'Dunkirk']
    })
  },
})

Mirage also comes with an in-memory database to help you model more complex data relationships.

createServer({
  models: {
    movie: Model.extend({
      castMembers: hasMany(),
    }),
    castMember: Model.extend({
      movie: belongsTo(),
    }),
  },
  routes() {
    // Your route handlers responding with the data.
  },
})

Mock Service Worker

MSW models its interception API after server-side routing and handles requests and responses according to the Fetch API specification, using the same classes you would use normally in JavaScript:

http.get('/movies', () => {
  return HttpResponse.json(['Interstellar', 'Inception', 'Dunkirk'])
})

Although MSW doesn’t ship data modeling capabilities built-in, it leverages ecosystem packages, like @mswjs/data, to give you a data-first approach to API mocking if you choose it.

import { factory, primaryKey, oneOf, manyOf } from '@mswjs/data'
 
// Model the data.
const db = factory({
  movie: {
    id: primaryKey(randomUuid),
    title: String,
    castMembers: manyOf('castMember'),
  },
  castMember: {
    id: primaryKey(randomUuid),
    name: String,
    movie: oneOf('movie'),
  },
})
 
// Generate request handlers based on the models.
// - GET /movies
// - GET /movies/:id
// - POST /movies
// - ...
db.toHandlers('rest')
 
// Including GraphQL queries!
// - query ListMovies
// - query GetMovie
// - mutation AddMovie
// - ...
db.toHandlers('graphql')

Cypress - cy.intercept()

Cypress is an end-to-end testing framework that provides API mocking capabilities through its cy.intercept() API.

API support

API typecy.intercept()Mock Service Worker
REST API
GraphQL API1
WebSocket API

1—Although it is possible to work with GraphQL requests through custom aliasing, it still requires a lot of additional setup. Cypress achieves GraphQL API mocking through HTTP handling (since GraphQL is most commonly implemented over HTTP on the web) instead of a first-class GraphQL support.

Supported environments

API typecy.intercept()Mock Service Worker
Node.js1
Browser

1—Cypress is a browser testing framework, which means you cannot use your cy.interecept() mocks in a Node.js process, like an integration test or a backend application.

Implementation

Environmentcy.intercept()Mock Service Worker
BrowserUses a browser-wide HTTP proxy to route outgoing requests through the custom server Cypress spawns as a part of its runtime.Uses a Service Worker to intercept requests on the browser level.

Integration

cy.intercept()Mock Service Worker
Requires no changes to the code. Available natively with Cypress.Requires no changes to the code.
Works with any request client without additional configuration.Works with any request client without additional configuration.

Definition

cy.intercept()

Cypress uses a custom matcher signature and a route handler function to intercept and handle requests. It utilizes custom methods like req.reply(), req.continue() or req.redirect() for more detailed request control.

cy.intercept('POST', '/users', {
  statusCode: 201,
  body: req.body,
  delay: 100,
})

Mock Service Worker

MSW models its interception API after server-side routing and handles requests and responses according to the Fetch API specification, using the same classes you would use normally in JavaScript:

import { http, delay } from 'msw'
 
http.post('/users', async ({ request }) => {
  // Read the request body as you would normally.
  const user = await request.json()
 
  // Control the response resolver execution flow
  // via Promises, like this "delay" Promise below.
  await delay(100)
 
  // Construct a response as you would normally.
  return HttpResponse.json(user, { status: 201 })
})

MSW gives you a more advanced control over the requests through its passthrough() and bypass() APIs, which still yield semantic HTTP responses under the hood.

Playwright - page.route()

Playwright is a browser testing tool that provides API mocking capabilities through its page.route() API.

API support

API typepage.route()Mock Service Worker
REST API
GraphQL API1
WebSocket API

1—You can handle GraphQL requests with page.route() since they are also HTTP requests but Playwright does not provide a first-class support for mocking GraphQL APIs.

Supported environments

API typepage.route()Mock Service Worker
Node.js1
Browser

1—Although with Playwright you write your tests in Node.js, Playwright itself (and its page.route()) only affect the traffic in the spawned browser, not the Node.js process.

Implementation

Environmentpage.route()Mock Service Worker
BrowserUses the Chrome DevTools Protocol to intercept requests on the browser level.Uses a Service Worker to intercept requests on the browser level.

Integration

page.route()Mock Service Worker
Does not require any changes to the code. Available natively with Playwright.Does not require any changes to the code.
Works with any request client without additional configuration.Works with any request client without additional configuration.

Definition

page.route()

The page.route() function in Playwright utilizes custom methods like route.fulfill() and route.continue() to give you more control over the request.

page.route('/fruits', async (route) => {
  const request = route.request()
 
  if (request.method === 'POST') {
    const response = await route.fetch()
    const json = await response.json()
    json.push({ name: 'Playwright' })
 
    return route.fulfill({ response, json })
  }
 
  route.continue()
})

Mock Service Worker

import { bypass } from 'msw'
 
http.post('/fruits', async ({ request }) => {
  const response = await fetch(bypass(request))
  const json = await response.json()
  json.push({ name: 'Mock Service Worker' })
 
  return HttpResponse.json(json, response)
})

The alternative for route.continue() in MSW is simply returning nothing from a response resolver. But since we can narrow down the request interception to both the method (POST) and path (/fruits), our request handler never concerns itself with other requests.

MSW uses the custom bypass() function that wraps any given Request instance to prevent it from being affected by any other otherwise matching request handlers.