miragejs: basic setup in react



~3 min read


454 words

We’ve been using MirageJS to mock out the APIs on our frontend apps and after playing around with it for a few weeks, I’m starting to really like how easy it makes it to quickly develop the frontend.1

I bootstrapped my latest project using a CRA template that my colleagues put together and it included a simple configuration for Mirage. I’ve pulled it out into a small Code Sandbox

To get a basic implementation of Mirage in a react app is really two pieces:

  1. Define the mirage server
  2. Instantiate the server

Defining The Mirage Server

A relatively simple server definition is in my mirage/setup.ts file:

import { Server as MirageServer, Response } from "miragejs"

export function serverConfig(Server: typeof MirageServer): MirageServer {
  return new Server({
    routes() {
      this.namespace = "api"

      this.get("ping", () => {
        return new Response(200, {}, { body: "pong" })
    environment: "development",

export async function mirageSetup() {
  const miragejs = await import("miragejs")
  return serverConfig(miragejs.Server)

The only real reason to separate it out like this is that it makes it easier to keep track of what’s going on as the Server grows in scope.

Then, in the entry point for the app, we want to invoke it:

import * as React from "react"
import { render } from "react-dom"
import { mirageSetup } from "./mirage/setup"
import App from "./App"

async function startup() {
  await mirageSetup()
const rootElement = document.getElementById("root")
render(<App />, rootElement)

The purpose of using a separate function setup rather than calling mirageSetup directly is because, again, that function can be extended to include other start up behavior. For example, in my app, I’ll check for the process.env.NODE_ENV and, if it’s a development / testing environment, I’ll add additional global context that my app would normally have when running in production.

There are a hundred ways to get up and running with Mirage and there are official guides. The reason I like this approach though is how it hides away the details in other files that you don’t need to concern yourself with when you want to look at your actual app. If you want to add a new route, well, then you go to your mirage setup and add it, but other than that, it’s hidden from view. Obviously, it’s a more opinionated approach, but sometimes, I like someone telling me how to do things! One less decision to make myself.


  • 1 It’s worth noting that just because MirageJS makes it easy to mock out responses doesn’t mean that it’s not worth considering up front what the shape of the response should be from the backend if you’re using a traditional REST endpoint.

Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!