โ† All guides

A Mirage JS alternative you don't have to maintain

Credit where it's due: Mirage more or less invented the "build the whole frontend before the backend exists" workflow. The ORM, models with belongsTo/hasMany, factories, serializers, route shorthands โ€” it's a genuinely elegant DSL, and a generation of Ember (and later React and Vue) developers shipped features against APIs that didn't exist yet because of it.

But if you're on this page you've probably hit one of the reasons people search for a Mirage JS alternative in 2026:

Mockbird is the hosted other half: a stateful mock REST API on a real URL. Define resources (or pick a preset, or import an OpenAPI spec / db.json / CSV / Postman collection), get realistic seeded data, full CRUD, relations, and error/latency injection โ€” reachable from a browser, curl, Postman, a phone, a backend, CI, or a teammate. Nothing to install, nothing to maintain, no signup.

The 60-second version

# one curl, no signup โ€” a whole seeded e-commerce backend
curl -X POST https://HOST/api/projects \
  -H 'content-type: application/json' -d '{"name":"shop","preset":"ecommerce"}'
# โ†’ {"id":"abc123","adminKey":"KEY", ...}   โ† save both

curl https://HOST/m/abc123/products?limit=3
# โ†’ 3 seeded products, CORS on, writes persist

Prefer clicking? This link creates the same project in your browser โ€” no account. Have an OpenAPI spec of your real API? Paste it at /app#import and mock your actual shapes.

Mirage concepts โ†’ Mockbird

MirageMockbirdNotes
this.resource('products') shorthanda products resourcelist/get/create/update/delete generated, plus filtering, sorting, pagination, search
Factories + server.createList(โ€ฆ)seeded realistic recordstyped field types (names, emails, prices, dates, enums) โ€” no factory code; or import your exact records from db.json/CSV
belongsTo / hasManyrefId fields + ?_expand / ?_embedplus nested routes like /products/1/reviews
timing: 400?mock_delay=400plus ?mock_jitter random latency and ?mock_chaos=0.3 random failures
new Response(500) in a handler?mock_status=500 on any URLno handler edit, no rebuild โ€” error/loading states guide
Serializers (root keys, envelopes)?mock_envelopewrap lists as {"data":[โ€ฆ]} or any custom template, per request or project-wide
Scenarios / seeds filessnapshotssave named data states; serve any GET from one via X-Mockbird-Snapshot โ€” parallel test workers don't race
server.db.dump()GET /m/:project/db.jsonfull dataset out anytime โ€” works verbatim with json-server; no lock-in
Route handlers with JS logiccustom routes with templatinghonest: templating is less powerful than arbitrary JS
this.passthrough()not neededMockbird is a base URL you point at โ€” real API calls are never intercepted in the first place
GraphQL via graphql-mirage addonsgenerated GraphQL endpointtyped schema from your resources, GraphiQL included

Try it in 10 seconds (shared demo, no setup)

# seeded data with field projection
curl 'https://HOST/m/demo/products?limit=2&select=name,price'

# relations without factory wiring
curl 'https://HOST/m/demo/reviews?limit=1&_expand=product'

# the states you'd write route handlers for โ€” as query params
curl -i 'https://HOST/m/demo/products?mock_status=503'
curl 'https://HOST/m/demo/products/1?mock_delay=2000'

# stateful: the write persists
curl -X POST https://HOST/m/demo/products \
  -H 'content-type: application/json' -d '{"name":"proof","price":9.99}'
# โ†’ returns {"id":31,โ€ฆ} โ€” and GET /m/demo/products/31 now works

All against the shared demo project (resets daily).

Migrating an existing Mirage setup

Honest comparison

Mirage JSMockbird
What it isfree OSS library (JS)free hosted service
Maintenancelast npm release Oct 2023 (0.1.48)actively developed โ€” nothing for you to maintain either way
Reachable fromyour JS app's process onlyanything with HTTP: browser, curl, Postman, mobile, backend, CI, agents
Setupinstall + server file: models, factories, routes, seedsone curl or one click; no code
Mock datafactories you writeseeded realistic data, or import your own
Relationsexcellent ORM (belongsTo/hasMany)_expand/_embed + nested routes; less expressive than a real ORM
Stateful CRUDyes (in-memory, resets on reload)yes โ€” persists across reloads, days, and machines
Error/latency simulationper-route code (timing, Response)?mock_status / ?mock_delay / ?mock_chaos / ?mock_jitter on any URL
Works offlineyes โ€” no network at allno โ€” it's a real network call
Mocks the real URL transparentlyyes โ€” intercepts your actual API hostno โ€” you point your app at a Mockbird base URL
Dynamic programmable responsesfull JS โ€” anything you can codetemplated custom routes; less powerful than arbitrary code
Shareablevia your repo + dev buildvia URL โ€” nothing to install
Request capnone10,000/project/day

Written by the Mockbird maker โ€” bias disclosed. Where Mirage genuinely wins: it runs entirely offline with zero latency, transparently mocks your real API URLs without touching app config, its ORM handles relational test data more expressively than anything URL-based, and route handlers are arbitrary JavaScript. If you have a healthy Mirage setup in fast unit tests, keep it. If you're choosing tooling today โ€” or the thing you need is a URL that a phone, a teammate, CI, or curl can hit โ€” that's us. (Maintenance facts checked July 2026 against npm and the miragejs GitHub repo; if they've shipped since, good โ€” the URL boundary above still stands.)

Full API reference in the docs. More guides: MSW alternative ยท mock API for React ยท mock API for Vue ยท deterministic test data ยท free mock API tools compared. Create your API โ†’