An extremely simple way to mock globalThis.fetch.

Read the documentation, or see "Usage" below.


1. Setup

Import the library and install the mock. Any fetches after calling install() will throw an error if you haven't explicitly added a mock for that route.

import * as mf from "";

// Replaces globalThis.fetch with the mocked copy

2. Mocking routes

Call mock with a route (optionally starting with a method specifier, eg. DELETE@) and a function (can be async). Whenever that route is fetched, the function will be executed and the response will be returned.

The route uses URLPattern, which allows you to match patterns and wildcards.

Only the path name will be used to match a handler, so you can use literally anything for the host when fetching.

mf.mock("GET@/api/hello/:name", (_req, params) => {
  return new Response(`Hello, ${params["name"]}!`, {
    status: 200,

const res = await fetch("https://localhost:1234/api/hello/SeparateRecords");
const text = await res.text(); //=> "Hello, SeparateRecords!"

3. Teardown

You can remove a single route's handler with remove, or reset all handlers with reset. Once the handler has been removed, that route will go back to throwing.

// OR: mf.reset()

await fetch("");
// UnhandledRouteError: GET /api/hello/world (0 routes have handlers)

To restore the original fetch, call uninstall.


Advanced usage

You don't have to replace the global fetch, or even have global state, by using the sandbox function. The returned object provides the same methods as the module (minus install & uninstall). Calling these methods will not alter global state.

// Ky is an excellent and easy-to-use fetch wrapper.
import ky from "";

// This object can also be destructured.
const mockFetch = mf.sandbox();

// Make a ky instance that uses mocked fetch - never touching the global fetch.
// Using a prefix URL means you won't need to write the URL every time.
const myKy = ky.extend({
  fetch: mockFetch.fetch,
  prefixUrl: "",

// Now you can mock the routes like normal
mockFetch.mock("PUT@/blog/posts", async (req) => {
  return new Response(/* ... */);

myKy.put("blog/posts", {
  /* ... */

You can destructure it, too.

const { fetch, mock, remove, reset} = mf.sandbox();


@eliassjogreen's tiny router (source) does the bulk of the work. It's general-purpose, but works great for Deno Deploy.