dist/plugins/web-mocks-msw/skills/web-mocks-msw/SKILL.md
MSW handlers, browser/server workers, test data. Use when setting up API mocking for development or testing, creating mock handlers with variants, or sharing mocks between browser and Node environments.
npx skillsauth add agents-inc/skills web-mocks-mswInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Quick Guide: Handlers with variant switching (default, empty, error). Shared between browser (dev) and Node (tests). Separate mock data from handlers for reusability. Type-safe using your API's generated types. Use
setupWorker(browser) andsetupServer(Node) -- never swap them.
Detailed Resources:
<critical_requirements>
(You MUST separate mock data from handlers - handlers in handlers/, data in mocks/)
(You MUST use setupWorker for browser/development and setupServer for Node/tests - NEVER swap them)
(You MUST reset handlers after each test with server.resetHandlers() in afterEach)
(You MUST use named constants for HTTP status codes and delays - NO magic numbers)
</critical_requirements>
Auto-detection: MSW, msw, mock handlers, mock data, API mocking, setupWorker, setupServer, http.get, HttpResponse
When to use:
When NOT to use:
Key patterns covered:
server.use()MSW intercepts network requests at the service worker (browser) or class extension (Node) level, providing realistic API mocking without changing application code. Keep mock data separate from handlers for reusability, type handlers against your generated API types, and organize handlers by domain/feature.
</philosophy>Define mock data as typed constants separate from MSW handlers. This enables type safety from your generated API types and reusability across handlers.
// mocks/features.ts
import type { GetFeaturesResponse } from "./api-types";
export const defaultFeatures: GetFeaturesResponse = {
features: [
{ id: "1", name: "Dark mode", status: "done" },
{ id: "2", name: "Auth", status: "in progress" },
],
};
export const emptyFeatures: GetFeaturesResponse = { features: [] };
For full variant handler examples, see examples/core.md.
When not to use: When mock data is truly one-off and specific to a single test case (use inline data in the test instead).
Create handlers that support multiple response scenarios (default, empty, error) with runtime switching for development and explicit overrides for testing.
import { http, HttpResponse } from "msw";
const API_ENDPOINT = "api/v1/features";
const HTTP_STATUS_OK = 200;
const HTTP_STATUS_INTERNAL_SERVER_ERROR = 500;
export const getFeaturesHandlers = {
defaultHandler: () =>
http.get(API_ENDPOINT, () =>
HttpResponse.json(defaultFeatures, { status: HTTP_STATUS_OK }),
),
emptyHandler: () =>
http.get(API_ENDPOINT, () =>
HttpResponse.json(emptyFeatures, { status: HTTP_STATUS_OK }),
),
errorHandler: () =>
http.get(
API_ENDPOINT,
() =>
new HttpResponse("Server error", {
status: HTTP_STATUS_INTERNAL_SERVER_ERROR,
}),
),
};
For full implementation with runtime switching, see examples/core.md.
setupWorker from msw/browser for browser/developmentsetupServer from msw/node for Node/testssetupWorker needs service worker APIs, setupServer needs Node APIs// browser-worker.ts
import { setupWorker } from "msw/browser";
export const browserWorker = setupWorker(...handlers);
// server-worker.ts
import { setupServer } from "msw/node";
export const server = setupServer(...handlers);
For browser app integration (SPA and SSR), see examples/browser.md.
Always follow this lifecycle to prevent test pollution:
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
Use server.use() for per-test overrides -- they are automatically cleaned up by resetHandlers().
For per-test override examples, see examples/core.md.
</patterns><red_flags>
setupWorker in Node tests or setupServer in browser -- wrong API for environment causes cryptic failuresafterEach(() => server.resetHandlers())) -- causes test pollutionawait when starting browser worker before render -- race conditions cause intermittent failuresonUnhandledRequest configuration -- unclear which requests are mocked vs realGotchas & Edge Cases:
delay() with no arguments is automatically negated in Node.js -- use explicit duration if you need delay in testsserver.use() persist until resetHandlers() -- they do NOT auto-reset between testshttp.all() matches any HTTP method on a path -- convenient but can mask bugs if overusedSee reference.md for detailed anti-pattern examples.
</red_flags>
<critical_reminders>
(You MUST separate mock data from handlers - handlers in handlers/, data in mocks/)
(You MUST use setupWorker for browser/development and setupServer for Node/tests - NEVER swap them)
(You MUST reset handlers after each test with server.resetHandlers() in afterEach)
(You MUST use named constants for HTTP status codes and delays - NO magic numbers)
Failure to follow these rules will cause test pollution, environment-specific failures, and hard-to-debug race conditions.
</critical_reminders>
development
Material Design component library for Vue 3
development
VitePress 1.x — Vue-powered static site generator for documentation sites, built on Vite
tools
Docusaurus 3.x documentation framework — site configuration, docs/blog plugins, sidebars, versioning, MDX, swizzling, and deployment
development
TanStack Form patterns - useForm, form.Field, validators, arrays, linked fields, createFormHook, type safety