CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-msw-storybook-addon

Mock API requests in Storybook with Mock Service Worker.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

worker-management.mddocs/

Worker Management

Functions for managing the MSW worker/server instance, including access and runtime handler management. These functions provide low-level control over the MSW instance for advanced use cases.

Capabilities

Get Worker Function

Returns the currently active MSW worker or server instance for direct manipulation.

/**
 * Get the current MSW worker/server instance
 * @returns SetupWorker (browser) or SetupServer (Node.js/React Native)
 * @throws Error if no worker is initialized
 */
function getWorker(): SetupWorker | SetupServer;

Usage Examples:

import { initialize, getWorker } from "msw-storybook-addon";
import { http, HttpResponse } from "msw";

// Initialize MSW first
initialize();

// Get the worker instance
const worker = getWorker();

// Add handlers at runtime
worker.use(
  http.get("/api/dynamic", () => {
    return HttpResponse.json({ timestamp: Date.now() });
  })
);

// Reset all handlers
worker.resetHandlers();

// Listen to request events (browser only)
if ('events' in worker) {
  worker.events.on('request:start', ({ request }) => {
    console.log('Request started:', request.url);
  });
}

Worker Instance Methods

The returned worker instance provides access to MSW's full API:

Browser Worker (SetupWorker)

// MSW types imported from 'msw'
import type { RequestHandler } from 'msw';
import type { SetupWorker } from 'msw/browser';
import type { SetupServer } from 'msw/node';

interface SetupWorker {
  /** Add request handlers to the worker */
  use(...handlers: RequestHandler[]): void;
  
  /** Remove specific request handlers */
  restoreHandlers(): void;
  
  /** Reset all request handlers to initial state */
  resetHandlers(...handlers: RequestHandler[]): void;
  
  /** Stop the service worker */
  stop(): void;
  
  /** Event emitter for request lifecycle events */
  events: {
    on(event: string, listener: Function): void;
    off(event: string, listener: Function): void;
  };
}

Node.js/React Native Server (SetupServer)

interface SetupServer {
  /** Add request handlers to the server */
  use(...handlers: RequestHandler[]): void;
  
  /** Remove specific request handlers */
  restoreHandlers(): void;
  
  /** Reset all request handlers to initial state */
  resetHandlers(...handlers: RequestHandler[]): void;
  
  /** Stop the server */
  close(): void;
  
  /** Event emitter for request lifecycle events */
  events: {
    on(event: string, listener: Function): void;
    off(event: string, listener: Function): void;
  };
}

Runtime Handler Management

Adding Handlers Dynamically

import { getWorker } from "msw-storybook-addon";
import { http, HttpResponse } from "msw";

const worker = getWorker();

// Add new handlers
worker.use(
  http.get("/api/users/:id", ({ params }) => {
    return HttpResponse.json({ 
      id: params.id, 
      name: `User ${params.id}` 
    });
  }),
  http.post("/api/users", async ({ request }) => {
    const userData = await request.json();
    return HttpResponse.json({ 
      id: Math.random().toString(),
      ...userData 
    });
  })
);

Resetting Handlers

import { getWorker } from "msw-storybook-addon";

const worker = getWorker();

// Reset to initial handlers (from initialize())
worker.resetHandlers();

// Reset and add new default handlers
worker.resetHandlers(
  http.get("/api/default", () => {
    return HttpResponse.json({ message: "Default response" });
  })
);

Restoring Handlers

import { getWorker } from "msw-storybook-addon";

const worker = getWorker();

// Temporarily override handlers
worker.use(
  http.get("/api/temp", () => {
    return HttpResponse.json({ temp: true });
  })
);

// Restore to previous state
worker.restoreHandlers();

Event Handling

Request Lifecycle Events

import { getWorker } from "msw-storybook-addon";

const worker = getWorker();

// Listen to request events
worker.events.on('request:start', ({ request }) => {
  console.log('Request started:', request.method, request.url);
});

worker.events.on('request:match', ({ request, handler }) => {
  console.log('Request matched:', request.url, 'by', handler.info.header);
});

worker.events.on('request:unhandled', ({ request }) => {
  console.log('Unhandled request:', request.method, request.url);
});

Cleanup Event Listeners

import { getWorker } from "msw-storybook-addon";

const worker = getWorker();

const requestHandler = ({ request }) => {
  console.log('Request:', request.url);
};

// Add listener
worker.events.on('request:start', requestHandler);

// Remove listener
worker.events.off('request:start', requestHandler);

Error Handling

Worker Not Initialized

If getWorker() is called before initialize():

try {
  const worker = getWorker();
} catch (error) {
  console.error(error.message);
  // "[MSW] Failed to retrieve the worker: no active worker found. Did you forget to call "initialize"?"
}

Platform-Specific Errors

import { getWorker } from "msw-storybook-addon";

const worker = getWorker();

// Check platform-specific features
if ('start' in worker) {
  // Browser worker - has start() method
  console.log('Running in browser');
} else if ('listen' in worker) {
  // Node.js/React Native server - has listen() method
  console.log('Running in Node.js/React Native');
}

Advanced Use Cases

Conditional Handler Setup

import { initialize, getWorker } from "msw-storybook-addon";
import { http, HttpResponse } from "msw";

// Initialize with base handlers
initialize({}, [
  http.get("/api/config", () => {
    return HttpResponse.json({ env: "test" });
  })
]);

// Add environment-specific handlers
const worker = getWorker();
if (process.env.NODE_ENV === 'development') {
  worker.use(
    http.get("/api/debug", () => {
      return HttpResponse.json({ debug: true });
    })
  );
}

Handler Composition

import { getWorker } from "msw-storybook-addon";
import { http, HttpResponse } from "msw";

const worker = getWorker();

// Base handlers
const baseHandlers = [
  http.get("/api/status", () => {
    return HttpResponse.json({ status: "ok" });
  })
];

// Feature-specific handlers  
const userHandlers = [
  http.get("/api/users", () => {
    return HttpResponse.json([]);
  })
];

// Apply composed handlers
worker.use(...baseHandlers, ...userHandlers);

docs

index.md

initialization.md

storybook-integration.md

worker-management.md

tile.json