agentleFS
anivaranivar/msw-skill/SKILL.md

msw

Skill2 starsChanged 9 days agoMITView on GitHub

MSW (Mock Service Worker) v2 and v3 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 and v2-to-v3 migration. Baseline: msw ^3.0.0. Triggers on: msw imports, http.get, http.post, HttpResponse, setupServer, setupWorker, graphql.query, sse, ws.link, mentions of "msw", "mock service worker", "api mocking", or "msw v3".

5 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions5 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 5

    1. PyModel/react-frontend-skills★ 23same name
    2. kriscard/Skills★ 15same name
    3. osabiohq/osabio★ 15same name
    4. thongdn-it/react-agent-skills★ 5same name
    5. Aver005/agent-skills★ 2same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repositoryOne other file it gives its agents.

The file

Files
SKILL.md

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. MSW v3 is ESM-only and requires Node.js >=22 and TypeScript >=5.9. 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 or v2 patterns when they conflict with the retrieved reference.

When to Use MSW

MSW is for API mocking at the network level — intercepting HTTP, GraphQL, Server-Sent Events (sse) and WebSocket (ws) traffic 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

// Imports
import { http, HttpResponse } from 'msw/http'
import { graphql } from 'msw/graphql'
import { sse } from 'msw/sse'
import { ws } from 'msw/ws'
import { delay } from 'msw/utils/delay'
import { bypass } from 'msw/utils/bypass'
import { passthrough } from 'msw/utils/passthrough'
import { setupServer } from 'msw/node'     // tests, SSR
import { setupWorker } from 'msw/browser'  // Storybook, dev
// React Native: import { setupServer } from '@msw/react-native'

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

// Server lifecycle (tests)
beforeAll(() => server.listen({ onUnhandledFrame: '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 are stripped — the handler over-matches the path
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.mdIn browsers, native Response drops Set-Cookie — use HttpResponse
Network errorsresponse-error-network.mdUse HttpResponse.error(); don't throw plain Errors
Streamingresponse-streaming.mdsse() for Server-Sent Events; ReadableStream for chunked

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 onUnhandledFrame: 'error'

GraphQL (MEDIUM)

RuleFileSummary
Response shapegraphql-response-shape.mdReturn { data } / { errors } via HttpResponse.json
Endpoint scopinggraphql-scope-with-link.mdOne graphql.link(url) per API; a wildcard link matches every endpoint

Utilities (MEDIUM)

RuleFileSummary
bypass vs passthroughutil-bypass-vs-passthrough.mdbypass() = new request; passthrough() = let through
delay behaviorutil-delay-behavior.mddelay() and delay('real') give no observable latency 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 } })

v2 to v3 Migration Quick Reference

MSW 3.0.0 is ESM-only and requires Node.js >=22 and TypeScript >=5.9 (v6/v7 also supported). The headline change: handlers and utilities are imported from subpath entrypoints instead of the package root. msw/graphql needs the optional peer dependency graphql (>=16) installed. See references/migration-v2-to-v3.md for the complete guide (and the official codemods).

v2v3
import { http, HttpResponse } from 'msw'import { http, HttpResponse } from 'msw/http'
import { graphql } from 'msw'import { graphql } from 'msw/graphql'
import { ws } from 'msw' / import { sse } from 'msw'msw/ws / msw/sse
import { delay } from 'msw'import { delay } from 'msw/utils/delay'
import { bypass, passthrough } from 'msw'msw/utils/bypass, msw/utils/passthrough
graphql.query(...) on the namespaceRemoved — link-first: graphql.link(url).query(...)
import { setupServer } from 'msw/native'@msw/react-native package replaces the msw/native entrypoint
handleRequest()Removed — use getResponse() (or experimental defineNetwork() for custom networks)
onUnhandledRequest: 'error'onUnhandledFrame: 'error' — covers requests AND WebSocket connections. Plain JavaScript ignores a leftover onUnhandledRequest, so the default 'warn' applies
Custom callback (request, print)Single { frame, defaults } object; narrow with frame instanceof HttpNetworkFrame (msw/experimental), call defaults.warn()
server.events.on('connection', ...)server.events.on('websocket:connection', ...) — life-cycle API only; the ws link's own addEventListener('connection') keeps its name
GraphQLLinkHandlers typeRenamed to GraphQLLink
LifeCycleEventsMap from mswPer-protocol maps (HttpNetworkFrameEventMap, WebSocketNetworkFrameEventMap) from msw/experimental
worker.stop() returns voidReturns a Promise — await worker.stop() for in-flight critical scenarios
:segments+ and :path* give an array (['user', 'privacy'])One string with slashes ('user/privacy'). The type still allows an array, so TypeScript does not report .join() on it
RegExp tokens in a string predicate ('/user/:id(\\d+)')Match no request. Use a RegExp predicate

New in v3: msw/vite plugin (serves the worker script — no more copying mockServiceWorker.js into public), GraphQL v17 and link-first subscriptions, the WebSocket Extension API, page-navigation and form-submission interception, passthrough request-header modification, and per-utility msw/utils/* modules for smaller bundles.

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
migration-v2-to-v3.mdComplete v2 to v3 breaking changes, new APIs, and migration guide
anti-patterns.md10 common mistakes with BAD/GOOD examples

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.