Skills msw

install
source · Clone the upstream repo
git clone https://github.com/openclaw/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/anivar/msw-skill" ~/.claude/skills/openclaw-skills-msw && rm -rf "$T"
OpenClaw · Install into ~/.openclaw/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/skills/anivar/msw-skill" ~/.openclaw/skills/openclaw-skills-msw && rm -rf "$T"
manifest: skills/anivar/msw-skill/SKILL.md
source content

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 internals
vi.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 DesignCRITICAL
handler-
4
2Setup & LifecycleCRITICAL
setup-
3
3Request ReadingHIGH
request-
2
4Response ConstructionHIGH
response-
3
5Test PatternsHIGH
test-
4
6GraphQLMEDIUM
graphql-
2
7UtilitiesMEDIUM
util-
2

All 20 Rules

Handler Design (CRITICAL)

RuleFileSummary
Use
http
namespace
handler-use-http-namespace.md
rest
is removed in v2 — use
http.get()
,
http.post()
No query params in URL
handler-no-query-params.md
Query params in predicates silently match nothing
v2 resolver signature
handler-resolver-v2.md
Use
({ request, params, cookies })
, not
(req, res, ctx)
v2 response construction
handler-response-v2.md
Use
HttpResponse.json()
, not
res(ctx.json())

Setup & Lifecycle (CRITICAL)

RuleFileSummary
Correct import paths
setup-import-paths.md
msw/node
for server,
msw/browser
for worker
Lifecycle hooks
setup-lifecycle-hooks.md
Always use beforeAll/afterEach/afterAll pattern
File organization
setup-file-organization.md
Organize in
src/mocks/
with handlers, node, browser files

Request Reading (HIGH)

RuleFileSummary
Clone in events
request-clone-events.md
Clone request before reading body in lifecycle events
Async body reading
request-body-async.md
Always
await request.json()
— body reading is async

Response Construction (HIGH)

RuleFileSummary
HttpResponse for cookies
response-use-httpresponse.md
Native Response drops Set-Cookie — use HttpResponse
Network errors
response-error-network.md
Use
HttpResponse.error()
, don't throw in resolvers
Streaming
response-streaming.md
Use ReadableStream for SSE/chunked responses

Test Patterns (HIGH)

RuleFileSummary
Test behavior
test-behavior-not-requests.md
Assert on UI/state, not fetch call arguments
Per-test overrides
test-override-with-use.md
Use
server.use()
for error/edge case tests
Concurrent isolation
test-concurrent-boundary.md
Wrap concurrent tests in
server.boundary()
Unhandled requests
test-unhandled-request.md
Set
onUnhandledRequest: 'error'

GraphQL (MEDIUM)

RuleFileSummary
Response shape
graphql-response-shape.md
Return
{ data }
/
{ errors }
via HttpResponse.json
Endpoint scoping
graphql-scope-with-link.md
Use
graphql.link(url)
for multiple GraphQL APIs

Utilities (MEDIUM)

RuleFileSummary
bypass vs passthrough
util-bypass-vs-passthrough.md
bypass()
= new request;
passthrough()
= let through
delay behavior
util-delay-behavior.md
delay()
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.params
params
from resolver info
req.body
await request.json()
req.cookies
cookies
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.md
http.*
and
graphql.*
methods, URL predicates, path params
response-api.md
HttpResponse
class, all static methods, cookie handling
server-api.md
setupServer
/
setupWorker
, lifecycle events,
boundary()
test-patterns.md
Vitest/Jest setup, overrides, concurrent isolation, cache clearing
migration-v1-to-v2.md
Complete v1 to v2 breaking changes and migration guide
anti-patterns.md
10 common mistakes with BAD/GOOD examples