Mocking backend with json-server and concurrently
When you’re building fullstack apps, switching constantly between frontend and backend can slow you down. Sometimes you’re waiting on the API to be ready. Sometimes you just want to test your UI against data - now.
This is where json-server and concurrently come in.
With just a few lines of config, you can mock a full REST API, seed it with custom data, and run it alongside your frontend - no waiting for real backend endpoints.
Why it’s worth using
As a frontend developer, this lets you:
- Develop UI before backend is ready
- Simulate different API states (empty, partial, paginated)
- Work offline or without a dev server
- Reduce friction when testing UI logic
As a fullstack dev, you gain:
- Flexibility: Build BO or FO first — whichever you feel like
- Easier onboarding for others (or your future self)
- Clean separation between layers while still moving fast
Step 1 – Install the tools
npm install -D json-server concurrently
Step 2 – Create a mock database
Create a file in the root of your project:
{
"users": [
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" }
],
"flashcards": [
{ "id": 1, "deck": "Spanish", "front": "hola", "back": "hello" },
{ "id": 2, "deck": "Spanish", "front": "adiós", "back": "goodbye" }
]
}
This gives you REST endpoints like:
-
GET /users -
GET /flashcards -
POST /flashcards -
PUT /flashcards/1 -
DELETE /users/2
Step 3 – Add scripts to package.json
{
"scripts": {
"dev": "concurrently \"npm:dev:fe\" \"npm:dev:api\"",
"dev:fe": "vite",
"dev:api": "json-server --watch db.json --port 5000"
}
}
Now just run:
npm run dev
And both the frontend and mock backend will start at once
Step 4 - Use a .env file
To make your mock API path easily swappable later, add this to .env:
VITE_API_URL=http://localhost:5000
Then in your frontend, fetch data like this (example in Vue):
const res = await fetch(`${import.meta.env.VITE_API_URL}/flashcards`);
const data = await res.json();
When you switch to a real backend, just update the .env file — no code changes needed.
Bonus - Custom routes or middlewares
Want to customize behavior? You can:
- Add a
routes.jsonfile to remap endpoints - Use
json-serverwith a JavaScript config to include your own middleware (e.g. for auth, artificial delays, logging, etc.)
Example routes.json:
{
"/api/users": "/users",
"/api/cards": "/flashcards"
}
Then run:
json-server --watch db.json --routes routes.json
You can also replace —watch with a JS config using json-server as a module if you want advanced control.
Summary
Using json-server + concurrently helps you:
-
Move faster
-
Mock data easily
-
Focus on building, not waiting
Perfect for:
-
Quick prototypes
-
Isolated frontend development
-
API integration testing
Once you try it, it’s hard to imagine going back.
Bartłomiej Nowak
Programmer
Programmer focused on performance, simplicity, and good architecture. I enjoy working with modern JavaScript, TypeScript, and backend logic — building tools that scale and make sense.