or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-msw

Seamless REST/GraphQL API mocking library for browser and Node.js.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/msw@2.11.x

To install, run

npx @tessl/cli install tessl/npm-msw@2.11.0

0

# Mock Service Worker (MSW)

1

2

Mock Service Worker (MSW) is an API mocking library that intercepts HTTP, GraphQL, and WebSocket requests at the network level using Service Workers in browsers and low-level interception in Node.js. Unlike traditional mocking libraries that stub fetch or axios functions, MSW operates transparently without modifying application code, allowing developers to reuse the same mock definitions across unit tests, integration tests, end-to-end tests, and local development.

3

4

## Package Information

5

6

- **Package Name**: msw

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install msw`

10

11

## Core Imports

12

13

```typescript

14

import { http, HttpResponse, setupWorker } from "msw";

15

import { setupServer } from "msw/node";

16

```

17

18

For CommonJS:

19

20

```javascript

21

const { http, HttpResponse, setupWorker } = require("msw");

22

const { setupServer } = require("msw/node");

23

```

24

25

Environment-specific imports:

26

27

```typescript

28

// Browser-specific

29

import { setupWorker } from "msw/browser";

30

31

// Node.js-specific

32

import { setupServer } from "msw/node";

33

34

// React Native-specific

35

import { setupServer } from "msw/native";

36

37

// Core-only imports

38

import { http } from "msw/core/http";

39

import { graphql } from "msw/core/graphql";

40

import { ws } from "msw/core/ws";

41

```

42

43

## Basic Usage

44

45

```typescript

46

import { http, HttpResponse, setupWorker } from "msw";

47

48

// Define request handlers

49

const handlers = [

50

// REST API handlers

51

http.get('/api/user', () => {

52

return HttpResponse.json({ name: 'John Doe', id: 123 });

53

}),

54

55

http.post('/api/login', async ({ request }) => {

56

const { username, password } = await request.json();

57

58

if (username === 'admin' && password === 'secret') {

59

return HttpResponse.json({ token: 'abc123' });

60

}

61

62

return HttpResponse.json(

63

{ error: 'Invalid credentials' },

64

{ status: 401 }

65

);

66

}),

67

68

// GraphQL handlers

69

graphql.query('GetUser', () => {

70

return HttpResponse.json({

71

data: { user: { name: 'John Doe' } }

72

});

73

}),

74

];

75

76

// Browser setup

77

const worker = setupWorker(...handlers);

78

worker.start();

79

80

// Node.js setup (for testing)

81

const server = setupServer(...handlers);

82

server.listen();

83

```

84

85

## Architecture

86

87

MSW is built around several key components:

88

89

- **Request Handlers**: Define how to intercept and respond to specific requests using Express-like routing

90

- **Setup APIs**: Platform-specific APIs (`setupWorker`, `setupServer`) that configure and control request interception

91

- **Response Utilities**: `HttpResponse` class and utilities for creating realistic mock responses

92

- **Network Interception**: Service Workers (browser) or low-level interceptors (Node.js) that capture requests transparently

93

- **Multi-Environment Support**: Same handler definitions work across browser, Node.js, and React Native environments

94

95

## Capabilities

96

97

### HTTP Request Handling

98

99

Intercept and mock HTTP requests using Express-like routing syntax with support for parameters, wildcards, and custom predicates.

100

101

```typescript { .api }

102

interface HttpRequestHandler {

103

<Params, RequestBodyType, ResponseBodyType>(

104

predicate: string | RegExp | ((info: { request: Request; parsedResult: any }) => boolean),

105

resolver: (info: {

106

request: Request;

107

params: Params;

108

cookies: Record<string, string>;

109

}) => Response | Promise<Response>,

110

options?: { once?: boolean }

111

): HttpHandler;

112

}

113

114

const http: {

115

all: HttpRequestHandler;

116

get: HttpRequestHandler;

117

post: HttpRequestHandler;

118

put: HttpRequestHandler;

119

delete: HttpRequestHandler;

120

patch: HttpRequestHandler;

121

head: HttpRequestHandler;

122

options: HttpRequestHandler;

123

};

124

```

125

126

[HTTP Handlers](./http-handlers.md)

127

128

### GraphQL Request Handling

129

130

Intercept and mock GraphQL operations by query/mutation name or operation type, with support for typed responses and scoped endpoints.

131

132

```typescript { .api }

133

interface GraphQLRequestHandler {

134

<Query, Variables>(

135

predicate: string | DocumentNode | ((info: { query: any; variables: any }) => boolean),

136

resolver: (info: {

137

query: Query;

138

variables: Variables;

139

request: Request;

140

}) => Response | Promise<Response>,

141

options?: { once?: boolean }

142

): GraphQLHandler;

143

}

144

145

const graphql: {

146

query: GraphQLRequestHandler;

147

mutation: GraphQLRequestHandler;

148

operation: (resolver: any) => GraphQLHandler;

149

link: (url: string) => typeof graphql;

150

};

151

```

152

153

[GraphQL Handlers](./graphql-handlers.md)

154

155

### WebSocket Connection Handling

156

157

Intercept and mock WebSocket connections with event-based API for handling connection lifecycle and message broadcasting.

158

159

```typescript { .api }

160

interface WebSocketLink {

161

clients: Set<WebSocketClient>;

162

addEventListener<EventType extends keyof WebSocketHandlerEventMap>(

163

event: EventType,

164

listener: (...args: WebSocketHandlerEventMap[EventType]) => void

165

): WebSocketHandler;

166

broadcast(data: WebSocketData): void;

167

broadcastExcept(

168

clients: WebSocketClient | WebSocketClient[],

169

data: WebSocketData

170

): void;

171

}

172

173

const ws: {

174

link: (url: string) => WebSocketLink;

175

};

176

```

177

178

[WebSocket Handlers](./websocket-handlers.md)

179

180

### Browser Environment Setup

181

182

Service Worker-based request interception for browser environments with lifecycle control and runtime handler management.

183

184

```typescript { .api }

185

interface SetupWorker {

186

start(options?: StartOptions): Promise<ServiceWorkerRegistration | undefined>;

187

stop(): void;

188

use(...handlers: RequestHandler[]): void;

189

resetHandlers(...handlers?: RequestHandler[]): void;

190

restoreHandlers(): void;

191

listHandlers(): ReadonlyArray<RequestHandler>;

192

events: LifeCycleEventEmitter;

193

}

194

195

function setupWorker(...handlers: RequestHandler[]): SetupWorker;

196

```

197

198

[Browser Setup](./browser-setup.md)

199

200

### Node.js Environment Setup

201

202

Low-level request interception for Node.js environments using HTTP/HTTPS module patching, ideal for testing scenarios.

203

204

```typescript { .api }

205

interface SetupServer {

206

listen(options?: { onUnhandledRequest?: 'bypass' | 'warn' | 'error' }): void;

207

close(): void;

208

use(...handlers: RequestHandler[]): void;

209

resetHandlers(...handlers?: RequestHandler[]): void;

210

restoreHandlers(): void;

211

listHandlers(): ReadonlyArray<RequestHandler>;

212

events: LifeCycleEventEmitter;

213

}

214

215

function setupServer(...handlers: RequestHandler[]): SetupServer;

216

```

217

218

[Node.js Setup](./nodejs-setup.md)

219

220

### React Native Environment Setup

221

222

Request interception for React Native applications using fetch and XMLHttpRequest interceptors, compatible with popular HTTP libraries.

223

224

```typescript { .api }

225

interface SetupServerCommonApi {

226

listen(options?: { onUnhandledRequest?: 'bypass' | 'warn' | 'error' }): void;

227

close(): void;

228

use(...handlers: RequestHandler[]): void;

229

resetHandlers(...handlers?: RequestHandler[]): void;

230

restoreHandlers(): void;

231

listHandlers(): ReadonlyArray<RequestHandler>;

232

events: LifeCycleEventEmitter;

233

}

234

235

function setupServer(...handlers: RequestHandler[]): SetupServerCommonApi;

236

```

237

238

[React Native Setup](./react-native-setup.md)

239

240

### Response Creation

241

242

Enhanced Response class with convenience methods for creating various response types with proper headers and content handling.

243

244

```typescript { .api }

245

class HttpResponse<BodyType> extends Response {

246

constructor(body?: BodyType | null, init?: HttpResponseInit);

247

248

static text(body?: string, init?: HttpResponseInit): HttpResponse<string>;

249

static json<T>(body?: T, init?: HttpResponseInit): HttpResponse<T>;

250

static xml(body?: string, init?: HttpResponseInit): HttpResponse<string>;

251

static html(body?: string, init?: HttpResponseInit): HttpResponse<string>;

252

static arrayBuffer(body?: ArrayBuffer, init?: HttpResponseInit): HttpResponse<ArrayBuffer>;

253

static formData(body?: FormData, init?: HttpResponseInit): HttpResponse<FormData>;

254

static error(): HttpResponse<any>;

255

}

256

257

interface HttpResponseInit extends ResponseInit {

258

type?: ResponseType;

259

}

260

```

261

262

[Response Creation](./response-creation.md)

263

264

### Command Line Interface

265

266

CLI tool for initializing and managing MSW Service Worker files in browser environments.

267

268

```bash { .api }

269

# Initialize MSW in project

270

msw init [publicDir] [--save] [--cwd <directory>]

271

272

# Examples:

273

msw init public/ --save

274

msw init ./static

275

msw init --cwd /path/to/project

276

```

277

278

[CLI Documentation](./cli.md)

279

280

### Request Utilities

281

282

Utilities for handling request flow, including delays, bypassing MSW interception, and passthrough behavior.

283

284

```typescript { .api }

285

function delay(duration?: number | 'real' | 'infinite'): Promise<void>;

286

function bypass(input: string | URL | Request, init?: RequestInit): Request;

287

function passthrough(): HttpResponse<any>;

288

function getResponse(

289

handlers: Array<RequestHandler>,

290

request: Request,

291

resolutionContext?: ResponseResolutionContext

292

): Promise<Response | undefined>;

293

```

294

295

[Request Utilities](./utilities.md)

296

297

## Types

298

299

```typescript { .api }

300

// Core handler types

301

type RequestHandler = HttpHandler | GraphQLHandler | WebSocketHandler;

302

303

interface RequestHandlerOptions {

304

once?: boolean;

305

}

306

307

// HTTP types

308

interface HttpHandler {

309

predicate: string | RegExp | HttpCustomPredicate;

310

resolver: HttpResponseResolver;

311

options: RequestHandlerOptions;

312

}

313

314

type HttpCustomPredicate = (info: {

315

request: Request;

316

parsedResult: HttpRequestParsedResult;

317

}) => boolean;

318

319

interface HttpRequestParsedResult {

320

match: Match;

321

query: RequestQuery;

322

}

323

324

type RequestQuery = Record<string, string | string[]>;

325

326

// GraphQL types

327

interface GraphQLHandler {

328

operationType: 'query' | 'mutation' | 'all';

329

predicate: string | DocumentNode | GraphQLCustomPredicate;

330

resolver: GraphQLResponseResolver;

331

}

332

333

type GraphQLCustomPredicate = (info: {

334

query: any;

335

variables: Record<string, any>;

336

operationType: string;

337

operationName?: string;

338

}) => boolean;

339

340

// WebSocket types

341

interface WebSocketHandler {

342

url: string | RegExp;

343

eventHandlers: Map<string, Function[]>;

344

}

345

346

type WebSocketData = string | ArrayBuffer | Blob;

347

348

// Setup types

349

interface StartOptions {

350

serviceWorker?: {

351

url?: string;

352

options?: RegistrationOptions;

353

};

354

quiet?: boolean;

355

onUnhandledRequest?: 'bypass' | 'warn' | 'error';

356

}

357

358

// Path matching types

359

type Path = string | RegExp;

360

type PathParams<T extends string = string> = Record<T, string>;

361

362

interface Match {

363

matches: boolean;

364

params: Record<string, string>;

365

}

366

367

// Response types

368

type DefaultBodyType = string | number | boolean | null | undefined | ArrayBuffer | Blob | FormData | ReadableStream;

369

type JsonBodyType = Record<string, any> | any[];

370

371

// Lifecycle types

372

interface LifeCycleEventsMap {

373

'request:start': [args: { request: Request; requestId: string }];

374

'request:match': [args: { request: Request; requestId: string }];

375

'request:unhandled': [args: { request: Request; requestId: string }];

376

'request:end': [args: { request: Request; requestId: string }];

377

'response:mocked': [args: { response: Response; request: Request; requestId: string }];

378

'response:bypass': [args: { response: Response; request: Request; requestId: string }];

379

'unhandledException': [args: { error: Error; request: Request; requestId: string }];

380

}

381

382

type LifeCycleEventEmitter = {

383

on<EventType extends keyof LifeCycleEventsMap>(

384

event: EventType,

385

listener: (...args: LifeCycleEventsMap[EventType]) => void

386

): void;

387

removeListener<EventType extends keyof LifeCycleEventsMap>(

388

event: EventType,

389

listener: (...args: LifeCycleEventsMap[EventType]) => void

390

): void;

391

removeAllListeners(event?: keyof LifeCycleEventsMap): void;

392

};

393

394

// Utility types

395

type DelayMode = 'real' | 'infinite';

396

type ResponseResolutionContext = {

397

baseUrl?: string;

398

};

399

400

// Deprecated types (for backward compatibility)

401

/** @deprecated Use HttpResponse instead */

402

type StrictResponse<BodyType> = HttpResponse<BodyType>;

403

404

// Legacy type aliases

405

type DefaultRequestMultipartBody = Record<string, string | File>;

406

```