Life-cycle events

Life-cycle events allow you to subscribe to the internal library events occurring during the request/response handling. You are unlikely to use this API directly while developing or testing with MSW. There are, however, a number of use-cases when this API can be beneficial:

  • When you’re building a third-party library encapsulating MSW;
  • When you wish to transparently monitor requests/responses in your application;
  • When you wish to explicitly wait for a certain request/response.



The life-cycle events API is read-only. This means that you can observe requests and responses but cannot affect them. If you wish to affect the request handling, consider using setupWorker and/or setupServer instead.

Clone before reading

The request and response references exposed through this API are exact Fetch API representations of the occurred requests and received responses. If you wish to read their bodies, don’t forget to clone them.'request:start', async ({ request }) => {
  // Read the request body as text for every request
  // that occurs in your application.
  const payload = await request.clone().text()


The life-cycle events API is exposed under the events property on the worker/server instance:

// In the browser.
const worker = setupWorker(...handlers)
// In Node.js.
const server = setupServer(...handlers)

The overall shape of the API is identical between the environments.

The events property contains a custom event emitter intentionally restricted to only listen to the events without the ability to emit them (emitting events is performed by the library). You can use methods like addListener(), once() and removeListener() on the events object.

// Observe any outgoing requests in your application.'request:start', ({ request, requestId }) => {
  console.log('Outgoing request:', request.method, request.url)

Request events


The request:start event is emitted whenever a request occurs in your application. You can access the request reference in the argument of the listener.'request:start', ({ request, requestId }) => {
  console.log('Outgoing request:', request.method, request.url)


The request:match event is emitted whenever an intercepted request has a corresponding request handler defined.


The request:unhandled event is emitted whenever an intercepted request has no corresponding request handler defined and will be performed as-is.


The request:end event is emitted whenever a request has ended. This event is emitted for all requests, regardless if they were handled or not.

Response events


The response:mocked event is emitted whenever a mocked response is sent. You can access both the response reference and the respective request reference in the listener to this event.'response:mocked', ({ request, requestId, response }) => {
    '%s %s received %s %s',


The response:bypass event is emitted whenever an original (bypassed) response is sent. Similar to the response:mocked event, you can access the response and request references in the listener.

Other events


The unhandledException event is emitted whenever an unhandled error is thrown within the response resolver function. You can access the relevant request and requestId in the listener to this event, as well as the thrown error reference.'unhandledException', ({ request, requestId, error }) => {
  console.log('%s %s errored! See details below.', request.method, request.url)

Removing listeners


  • name, String, the event name to remove.
  • listener, Function, the event listener to remove.'request:start', requestStartListener)


  • name, String (Optional), the event name to remove.

When called without any arguments, .removeAllListeners() removes all events attached to the current worker/server instance:

You can provide a name argument to only remove the listeners for the respective event:'request:start')