Stop Hardcoding JSON. Meet SimAPI — The Mock Backend Your Frontend Deserves
There’s a version of this story every frontend developer has lived through.
Stop Hardcoding JSON. Meet SimAPI — The Mock Backend Your Frontend Deserves

There’s a version of this story every frontend developer has lived through.
The design is approved. The Figma is pixel-perfect. The tickets are written. Your team is ready. And then — the backend API isn’t ready. Maybe it’s a week away. Maybe two. Maybe it’s a “we’ll let you know” situation.
So you do what you’ve always done: you hardcode some JSON. You write a few useState initialisers with fake data, slap a comment that says// TODO: replace with real API call, and you ship the feature behind a feature flag. It looks great in demos. It completely falls apart the moment a real backend touches it.
Because hardcoded JSON doesn’t have latency. It doesn’t throw validation errors. It doesn’t return a 401 when an auth token expires. It doesn’t return different shapes for lists versus single items. It doesn’t simulate what happens when your network is flaky at 2 am and your serverless function times out.
Hardcoded JSON lies to your frontend. And your frontend believes every word of it.
The Real Cost of the Waiting Game
This isn’t just a productivity problem. It’s a quality problem.
When your frontend is built against fake data, the gap between “works in development” and “works in production” widens with every commit. Edge cases get missed — not because your team isn’t thorough, but because the conditions that trigger those edge cases (slow responses, auth failures, malformed payloads) simply don’t exist in your dev environment.
By the time the real backend arrives, you’ve made thousands of implicit assumptions. The field is calleduser_name, not username. The list endpoint paginates with cursors, not page numbers. The auth endpoint returns a data wrapper that your frontend isn't accounting for. Each one of these is a bug you discover in production.
There’s a better way.
What is SimAPI?
SimAPI (@simapi/simapi) is a local-first backend simulator for developers. You define API endpoints as plain TypeScript objects. SimAPI spins up a real HTTP server — same HTTP methods, same status codes, same headers — that your frontend can call exactly like a production backend.
No service workers. No intercepted fetch calls. A real server, running locally, that your whole team (and your mobile app, and your Postman, and your automated tests) can hit.
Here’s what a full endpoint looks like:
import { AppResponse, faker, z, type EndpointDefinition } from "@simapi/simapi";
export const createPost: EndpointDefinition = {
path: "/api/posts",
method: "POST",
type: "secure", // 🔐 Requires authentication
request: { // You could also validate query parameters, headers and maybe even do it on a seperate request file
body: {
title: z.string().min(3),
body: z.string().min(10),
},
},
delay: 350, // ⏱️ Simulates a real DB write
failRate: 0.05, // 💥 5% chance of a 500 error
handler: (req) => {
return AppResponse.created({
data: {
id: faker.string.ulid(),
title: req.body("title"),
body: req.body("body"),
author: faker.person.fullName(),
createdAt: new Date().toISOString(),
},
});
},
};
That’s it. That’s a complete mock endpoint with authentication, Zod validation, realistic latency, fault injection, and a faker-generated response. No config files, no setup, no boilerplate.
The Simulation Stack
SimAPI isn’t just a “return some JSON” mock server. It simulates the full lifecycle of a real API request.
Real Request Validation
Using Zod — the de facto TypeScript validation library — you can validate the request body, query string, and headers before your handler ever runs. When validation fails, SimAPI returns a properly formatted 422 Unprocessable Entity response.
You can even configure the error format globally:
// simapi.config.ts
export default defineConfig({
autoThrowValidationErrors: "laravel", // matches Laravel's validation format
});
No more discovering that your error-handling component only works for Zod-shaped errors.
Authentication Simulation
Mark an endpoint as, type: "secure" and SimAPI will reject unauthenticated requests with a 401. You define your own auth handler — Bearer tokens, API keys, JWTs — and SimAPI enforces it across all secure endpoints.
// src/authHandler.ts
import { AppResponse, type AppRequest } from "@simapi/simapi";
export default function authHandler(req: AppRequest) {
const token = req.header("Authorization");
if (!token?.startsWith("Bearer ")) {
return AppResponse.unauthenticated();
}
// validate token...
}
Your frontend’s auth logic is now testable from day one.
Persistent Request Logging
Every request is logged to a database (SQLite by default, with libSQL and Postgres support). Not just console output — structured rows you can query, filter, and inspect.
This pairs with the SimAPI Console — an optional browser UI that gives you live request logs, an interactive schema browser, and a built-in “Try It” panel for firing test requests without leaving your terminal.
Realistic Data Generation
SimAPI re-exports faker from faker-js. Every call to your endpoint gets fresh, realistic fake data: unique IDs, real-looking names, believable email addresses, sentences, paragraphs. Not "string". Not "test".
Getting Started in 60 Seconds
npx @simapi/simapi@latest init my-api
cd my-api
npm run dev # or npm run serve to serve without watching
Your server is live at http://localhost:3000. Files in src/ are watched — the server restarts automatically on every save. No Docker, no database setup, no configuration.
The project structure it scaffolds:
my-api/
├── src/
│ ├── endpoints/ # Every named export is auto-discovered
│ ├── requests/ # Zod validation schemas
│ ├── models/ # Faker factory functions
│ └── authHandler.ts
├── simapi.config.ts
└── package.json
Already Have an OpenAPI Spec? Perfect.
If your backend team has already defined an OpenAPI spec (even a draft), SimAPI can generate endpoint stubs from it in one command:
simapi import openapi.json
It generates typed TypeScript stubs — with Zod validators wired from the request body schema — organised intelligently by path. /auth/verification/send and /auth/verification/verify end up in authVerification.ts. /users/{id} and /users end up in users.ts. Exactly what you'd expect.
And when you’re done? You can export your mock as an OpenAPI spec for the backend team:
simapi export --output api.json
The loop closes. Your mock becomes the contract.
How SimAPI Compares to the Alternatives

- vs. Postman Mocks: SimAPI lives in your repository. It’s version-controlled, works offline, and doesn’t cost a cloud subscription.
- vs. MSW (Mock Service Worker): MSW is excellent for browser testing, but it’s a browser API. It doesn’t help your mobile app, your Postman tests, or your CI pipeline. SimAPI is a real server that any HTTP client can call.
- vs. JSON-Server: JSON-Server returns JSON from a file. SimAPI runs functions. The difference is everything: conditional logic, auth flows, validation errors, randomised responses, stateful counters.
Deploy it. Seriously.
SimAPI projects can be deployed and shared with your team. Run simapi build to compile your project to a single optimised Node.js bundle:
simapi build # → .simapi/dist/server.mjs
simapi start # → runs the compiled bundle
Or deploy to a serverless platform with zero extra config:
- Vercel — run
simapi setup vercel, push to GitHub, done. - Netlify — run
simapi setup netlify, same story. - Docker — run
simapi setup docker, get aDockerfile. - Railway, Fly.io, Render — they’re all just Node.js.
Your entire team — frontend, mobile, QA — can all hit the same shared mock server. No more “works on my machine” discrepancies.
The Real Benefit: Confidence
The best thing about SimAPI isn’t the features list. It’s what it does to your development process.
When you build your feature against a SimAPI mock — one with real validation, real auth, real latency, real error cases — you’re not building against assumptions. You’re building against behaviour. When the real backend ships, the integration is mostly a drop-in.
The bugs that usually show up on day one of real API integration? Most of them were silently caught months earlier, in your local SimAPI server, before you even opened a PR.
Try It
npx @simapi/simapi@latest init my-api
📖 Documentation: simapi.mayrlabs.com 💻 GitHub: github.com/SimAPI/simapi 📦 npm: @simapi/simapi
I’d love to hear what you build. Drop a comment, open an issue, or just say hi.
메타데이터
- post_id
- 83a22965bb86
- slug
- stop-hardcoding-json-meet-simapi-the-mock-backend-your-frontend-deserves-83a22965bb86
- url
- https://medium.com/@youngmayor/stop-hardcoding-json-meet-simapi-the-mock-backend-your-frontend-deserves-83a22965bb86
- canonical_url
- https://medium.com/@youngmayor/stop-hardcoding-json-meet-simapi-the-mock-backend-your-frontend-deserves-83a22965bb86
- author_url
- https://medium.com/@youngmayor
- status
- ok
- fetched_at
- 2026-07-24 01:22:17