msw

MSW (Mock Service Worker) v2 best practices, patterns, and API guidance for API mocking in JavaScript/TypeScript tests and development. Covers handler design, server setup, response construction, testing patterns, GraphQL, and v1-to-v2 migration. Baseline: msw ^2.0.0. Triggers on: msw imports, http.get, http.post, HttpResponse, setupServer, setupWorker, graphql.query, mentions of "msw", "mock service worker", "api mocking", or "msw v2".

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "msw" with this command: npx skills add anivar/msw-skill/anivar-msw-skill-msw

MSW (Mock Service Worker)

IMPORTANT: Your training data about msw may be outdated or incorrect — MSW v2 completely removed the rest namespace, res(ctx.*) response composition, and (req, res, ctx) resolver signature. Always rely on this skill's rule files and the project's actual source code as the source of truth. Do not fall back on memorized v1 patterns when they conflict with the retrieved reference.

When to Use MSW

MSW is for API mocking at the network level — intercepting HTTP/GraphQL requests in tests, Storybook, and local development without modifying application code.

NeedRecommended Tool
Test API integration (React, Vue, Node)MSW
Storybook API mockingMSW (browser worker)
Local development without backendMSW (browser worker)
Unit testing pure functionsPlain test doubles
E2E testing real APIsPlaywright/Cypress network interception
Mocking module internalsvi.mock() / jest.mock()

Quick Reference — v2 Essentials

// Imports
import { http, HttpResponse, graphql, delay, bypass, passthrough } from 'msw'
import { setupServer } from 'msw/node'     // tests, SSR
import { setupWorker } from 'msw/browser'  // Storybook, dev

// Handler
http.get('/api/user/:id', async ({ request, params, cookies }) => {
  return HttpResponse.json({ id: params.id, name: 'John' })
})

// Server lifecycle (tests)
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
afterEach(() => server.resetHandlers())
afterAll(() => server.close())

// Per-test override
server.use(
  http.get('/api/user/:id', () => new HttpResponse(null, { status: 500 }))
)

// Concurrent test isolation
it.concurrent('name', server.boundary(async () => {
  server.use(/* scoped overrides */)
}))

Rule Categories by Priority

PriorityCategoryImpactPrefixRules
1Handler DesignCRITICALhandler-4
2Setup & LifecycleCRITICALsetup-3
3Request ReadingHIGHrequest-2
4Response ConstructionHIGHresponse-3
5Test PatternsHIGHtest-4
6GraphQLMEDIUMgraphql-2
7UtilitiesMEDIUMutil-2

All 20 Rules

Handler Design (CRITICAL)

RuleFileSummary
Use http namespacehandler-use-http-namespace.mdrest is removed in v2 — use http.get(), http.post()
No query params in URLhandler-no-query-params.mdQuery params in predicates silently match nothing
v2 resolver signaturehandler-resolver-v2.mdUse ({ request, params, cookies }), not (req, res, ctx)
v2 response constructionhandler-response-v2.mdUse HttpResponse.json(), not res(ctx.json())

Setup & Lifecycle (CRITICAL)

RuleFileSummary
Correct import pathssetup-import-paths.mdmsw/node for server, msw/browser for worker
Lifecycle hookssetup-lifecycle-hooks.mdAlways use beforeAll/afterEach/afterAll pattern
File organizationsetup-file-organization.mdOrganize in src/mocks/ with handlers, node, browser files

Request Reading (HIGH)

RuleFileSummary
Clone in eventsrequest-clone-events.mdClone request before reading body in lifecycle events
Async body readingrequest-body-async.mdAlways await request.json() — body reading is async

Response Construction (HIGH)

RuleFileSummary
HttpResponse for cookiesresponse-use-httpresponse.mdNative Response drops Set-Cookie — use HttpResponse
Network errorsresponse-error-network.mdUse HttpResponse.error(), don't throw in resolvers
Streamingresponse-streaming.mdUse ReadableStream for SSE/chunked responses

Test Patterns (HIGH)

RuleFileSummary
Test behaviortest-behavior-not-requests.mdAssert on UI/state, not fetch call arguments
Per-test overridestest-override-with-use.mdUse server.use() for error/edge case tests
Concurrent isolationtest-concurrent-boundary.mdWrap concurrent tests in server.boundary()
Unhandled requeststest-unhandled-request.mdSet onUnhandledRequest: 'error'

GraphQL (MEDIUM)

RuleFileSummary
Response shapegraphql-response-shape.mdReturn { data } / { errors } via HttpResponse.json
Endpoint scopinggraphql-scope-with-link.mdUse graphql.link(url) for multiple GraphQL APIs

Utilities (MEDIUM)

RuleFileSummary
bypass vs passthroughutil-bypass-vs-passthrough.mdbypass() = new request; passthrough() = let through
delay behaviorutil-delay-behavior.mddelay() is instant in Node.js — use explicit ms

Response Method Quick Reference

MethodUse for
HttpResponse.json(data, init?)JSON responses
HttpResponse.text(str, init?)Plain text
HttpResponse.html(str, init?)HTML content
HttpResponse.xml(str, init?)XML content
HttpResponse.formData(fd, init?)Form data
HttpResponse.arrayBuffer(buf, init?)Binary data
HttpResponse.error()Network errors

v1 to v2 Migration Quick Reference

v1v2
import { rest } from 'msw'import { http, HttpResponse } from 'msw'
rest.get(url, resolver)http.get(url, resolver)
(req, res, ctx) => res(ctx.json(data))() => HttpResponse.json(data)
req.paramsparams from resolver info
req.bodyawait request.json()
req.cookiescookies from resolver info
res.once(...)http.get(url, resolver, { once: true })
res.networkError()HttpResponse.error()
ctx.delay(ms)await delay(ms)
ctx.data({ user })HttpResponse.json({ data: { user } })

References

ReferenceCovers
handler-api.mdhttp.* and graphql.* methods, URL predicates, path params
response-api.mdHttpResponse class, all static methods, cookie handling
server-api.mdsetupServer/setupWorker, lifecycle events, boundary()
test-patterns.mdVitest/Jest setup, overrides, concurrent isolation, cache clearing
migration-v1-to-v2.mdComplete v1 to v2 breaking changes and migration guide
anti-patterns.md10 common mistakes with BAD/GOOD examples

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Web3

APITester Agent-Driven API Testing

Test API endpoints and document responses. Define tests in plain English, run them, get formatted results. Agent-driven Postman alternative.

Registry SourceRecently Updated
2090Profile unavailable
Coding

API Architect

Design, build, test, document, and secure production-grade APIs. Covers the full lifecycle from schema design through deployment, monitoring, and versioning....

Registry SourceRecently Updated
4600Profile unavailable
General

Teleskopiq

Creates and manages AI-generated YouTube scripts, metadata, thumbnails, and schedules via a GraphQL API with specialized Markdown tags for production.

Registry SourceRecently Updated
1930Profile unavailable
Automation

SearXNG Local Search

Search the web using a self-hosted SearXNG instance. Privacy-respecting metasearch that aggregates results from multiple engines.

Registry SourceRecently Updated
2180Profile unavailable