You’re building a frontend, but the backend is not ready. Use json-server when you need a local REST API backed by your own JSON file, or JSONPlaceholder when you just need a hosted fake API immediately.
Both tools help you keep coding instead of waiting for backend endpoints. This guide shows how to run json-server, call JSONPlaceholder, understand their limits, and know when to move to a schema-aware mock in Apidog.
For the broader concept, see what a mock API is. Here, we’ll focus on the two tools developers usually try first.
What is json-server?
json-server is an open-source npm package that turns a plain JSON file into a REST API.
You create a db.json file, run one command, and get CRUD endpoints for your resources:
GET /posts
GET /posts/:id
POST /posts
PUT /posts/:id
PATCH /posts/:id
DELETE /posts/:id
Write requests modify the JSON file, so changes persist while you develop locally.
Use json-server for:
- Frontend development before the backend exists
- UI prototypes
- Demo apps
- Local integration tests
- Quickly testing API workflows without a database
The project is available on GitHub.
Install and run json-server
Install it from npm:
npm install json-server
Create a db.json file:
{
"posts": [
{ "id": "1", "title": "First post", "views": 100 },
{ "id": "2", "title": "Second post", "views": 250 }
],
"comments": [
{ "id": "1", "text": "Nice work", "postId": "1" }
],
"profile": {
"name": "apidog"
}
}
Top-level arrays become collection routes. Top-level objects become single-resource routes.
Start the server:
npx json-server db.json
By default, it runs at:
http://localhost:3000
You now have a working local REST API.
Version note:
json-serverv1 removed the old--watchflag. Usenpx json-server db.json. Older tutorials may still showjson-server --watch db.jsonfor the 0.x version line.
Use the generated REST routes
Given the db.json above, json-server creates routes for posts.
GET /posts
GET /posts/:id
POST /posts
PUT /posts/:id
PATCH /posts/:id
DELETE /posts/:id
It also creates routes for the profile object:
GET /profile
PUT /profile
PATCH /profile
Try a request:
curl http://localhost:3000/posts
Create a post:
curl -X POST http://localhost:3000/posts \
-H "Content-Type: application/json" \
-d '{"id":"3","title":"Third post","views":10}'
Update it:
curl -X PATCH http://localhost:3000/posts/3 \
-H "Content-Type: application/json" \
-d '{"views":25}'
Delete it:
curl -X DELETE http://localhost:3000/posts/3
Query, sort, paginate, and embed related data
json-server also supports common query operations.
GET /posts?views:gt=100
GET /posts?views:lte=50
GET /posts?_sort=-views
GET /posts?_page=1&_per_page=25
GET /posts?_embed=comments
Examples:
curl "http://localhost:3000/posts?views:gt=100"
curl "http://localhost:3000/posts?_sort=-views"
curl "http://localhost:3000/posts?_page=1&_per_page=25"
Available operators include:
ltltegtgteeqneincontainsstartsWithendsWith
For a flat JSON file and one command, this gives you a useful REST surface for frontend development.
JSONPlaceholder: a fake API with zero setup
Sometimes you do not need custom data. You just need an API endpoint right now.
JSONPlaceholder is a hosted fake REST API from the same author:
Call it directly:
curl https://jsonplaceholder.typicode.com/posts/1
Example response:
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident",
"body": "quia et suscipit..."
}
It includes six ready-made resources:
-
/posts- 100 items -
/comments- 500 items -
/albums- 100 items -
/photos- 5000 items -
/todos- 200 items -
/users- 10 items
It also accepts POST, PUT, PATCH, and DELETE.
The important limitation: writes are fake. JSONPlaceholder returns a realistic response, but it does not save your changes.
That makes it useful for:
- Learning
fetch, Axios, or HTTP clients - Wiring up basic UI states
- Testing loading and rendering logic
- Building quick demos
It is not useful for stateful workflows that require saved data.
json-server vs JSONPlaceholder
| json-server | JSONPlaceholder | |
|---|---|---|
| Setup | Install npm package and write db.json
|
None |
| Runs | Locally | Hosted publicly |
| Custom data | Yes | No |
| Writes persist | Yes, to db.json
|
No, writes are faked |
| Best for | Prototypes with your own data shape | Quick demos and learning |
Use JSONPlaceholder when you need public sample data immediately.
Use json-server when you need:
- Your own resource names
- Your own fields
- Local persistence
- Basic CRUD behavior
Where these tools stop scaling
json-server and JSONPlaceholder are excellent for serving JSON quickly. They become limiting once your mock API needs to behave more like a real API.
Common issues:
-
No schema validation. You can post invalid data, and
json-serverwill store it. - No dynamic smart data. Responses come from a static file unless you manually change them.
-
Local-only by default. Teammates and CI cannot call your
localhost:3000. - Spec drift. Your fake data can diverge from your OpenAPI contract.
- No real saved writes in JSONPlaceholder. Stateful flows like carts, checkouts, and multi-step forms cannot be tested realistically.
If you need more options, see these roundups:
When to move to a schema-aware mock server
A schema-aware mock server helps when your frontend, backend, QA, and CI workflows need to rely on the same API contract.
This is where Apidog fits.
Instead of serving a static JSON file, Apidog mocks from your API definition.
That gives you:
- Schema-driven mocks. Define an endpoint or import an OpenAPI spec, then mock from the same contract.
- More realistic data. Apidog can generate values based on field names and types, such as emails, dates, numbers, and prices.
- Field-level mock rules. Configure specific mock behavior when you need deterministic values.
- Shareable cloud mock URLs. Your team and CI can call the same mock endpoint.
-
No per-project Node setup. You do not need to install a package or maintain a
db.jsonfile.
For realistic mock data, see:
Mock the same API in Apidog
To move from json-server to a schema-aware mock:
- Download Apidog.
- Create or open a project.
- Add an endpoint, for example:
GET /posts
- Define the response schema, or import an existing OpenAPI file.
- Use the generated mock URL.
- Add field-level mock rules if you need specific values.
- Share the mock URL with teammates or use it in tests and CI.
You keep the fast “API in minutes” workflow, but get schema alignment, realistic data, and a URL your whole team can use.
FAQ
Is json-server free?
Yes. json-server is open source and free to use. JSONPlaceholder is free too.
Does json-server persist data?
Yes. POST, PUT, PATCH, and DELETE write back to db.json.
JSONPlaceholder accepts write requests but does not save them.
Can I use json-server in production?
No. It is built for prototyping, demos, and testing. It does not provide production-grade validation, authentication, or scalability.
What is the difference between json-server and a mock server like Apidog?
json-server serves a static JSON file as an API.
Apidog mocks from your API schema, returns realistic data, and provides a shared cloud mock URL.
For more context, see:
How do I get realistic fake data instead of static rows?
Use a generator. A test data generator can create varied records, and Apidog can generate mock values from your schema.
The short version
Use json-server when you need a local REST API from your own JSON file. Use JSONPlaceholder when you need a hosted fake API with no setup.
Move to Apidog when you need schema-driven mocks, realistic data, shared mock URLs, and better alignment with your API contract. Download Apidog, import your spec, and start mocking from the same contract your real API will follow.


Top comments (0)