CLI tool
marmelab/json-graphql-server avatar
marmelab/json-graphql-server

json-graphql-server: a fake GraphQL API generated from a plain data file

Get a full fake GraphQL API with zero coding in less than 30 seconds.

1,948 stars167 forksJavaScriptMIT

At a glance

What is it?
json-graphql-server reads a JavaScript file of arrays and serves a complete GraphQL schema and mock API from it, inferring types from the values, wiring relations from foreign key style fields and generating filters, pagination and CRUD mutations along the way. It is Marmelab's answer to the complaint that learning GraphQL means reading a book and installing a gazillion packages.
Who is it for?
Adopt json-graphql-server when you are building a frontend against a GraphQL API that does not exist yet, or when you want a stable mock for tests, because the schema it generates is derived from real data rather than from a hand written SDL, so the shapes match what your fixtures contain. Do not adopt it as a production backend, because it is explicitly a testing and mocking tool, and the README documents no persistence, authentication or validation.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem is the first hour with GraphQL

json-graphql-server's pitch is a single sentence, to get a full fake GraphQL API with zero coding in less than 30 seconds, and the motivation section explains where that comes from. The README quotes a complaint that about every developer has felt, that they would love to learn GraphQL but it seems they first have to read a book about GraphQL types and queries and then install a gazillion npm packages. The tool is a testing and mocking tool for GraphQL written in Node.js, and it is explicitly inspired by json-server. That lineage explains the whole design. You write a data file, you run one command, and you get a server that behaves like the API your application expects, with the schema derived from the data rather than declared by hand. The developers named in the package manifest are François Zaninotto and Gildas Garcia, at Marmelab, and the project is MIT licensed, so the interesting question for an adopter is not whether the idea is sound, since it plainly is, but how much of the GraphQL surface it actually covers and where its conventions will surprise you.

One data file, one command

The contract is small. You create a `db.js` file that exports an object where the keys are the entity types and the values are lists of entities, that is, arrays of value objects with at least an `id` key.

js
module.exports = {
    posts: [
        { id: 1, title: "Lorem Ipsum", views: 254, user_id: 123 },
        { id: 2, title: "Sic Dolor amet", views: 65, user_id: 456 },
    ],
    users: [
        { id: 123, name: "John Doe" },
        { id: 456, name: "Jane Doe" }
    ],
    comments: [
        { id: 987, post_id: 1, body: "Consectetur adipiscing elit", date: new Date('2017-07-03') },
    ]
}

Then you start the server with `npx json-graphql-server <db_file_name>`, and it listens on localhost on port 3000. A different port is the `--port` or `-p` option, and a different host is `--host` or `-h`. To add it to a project as a dependency rather than running it through npx, the install line is `npm install -D json-graphql-server`, and the development dependency flag is the right one, because this is a tool for your machine and your tests rather than something you ship. The repository carries an `example/` directory with a `data.cjs` fixture, a `node/` example, a `browser/` example and a `schema.js`, and the package scripts include a `server` target that runs the binary against the example data, so you can see the whole thing working before you write your own file.

The generated schema, and how types are decided

Based on your data, the tool generates a schema with one type per entity, plus three query types and three mutation types. The example in the README for a `Post` entity shows the shape, with a single item query, a list query that takes paging, sorting and filtering arguments, a metadata query returning a count, and mutations to create, create many, update and delete.

graphql
type Query {
  Post(id: ID!): Post
  allPosts(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: PostFilter): [Post]
  _allPostsMeta(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: PostFilter): ListMetadata
}
type Mutation {
  createPost(data: String): Post
  createManyPost(data: [{data:String}]): [Post]
  updatePost(data: String): Post
  deletePost(id: ID!): Post
}

The type inference rules are the part to understand before you build fixtures. By convention every entity is expected to have an `id` field that is unique for its type, since it is treated as the primary key, and the type of every field is inferred from the values, so `Post.title` becomes a `String!` and `Post.views` an `Int!`. The non-null marker is a rule rather than a per field decision, because when all entities have a value for a field the field is made non nullable, which is why `Post.views` is `Int!` and not `Int`. That has a practical consequence. Add a record that is missing a field and the schema changes, so the mock and the fixtures have to be kept in step, and a frontend that was written against a non-null field can start failing against a schema that a new fixture record altered. The supported type table maps JavaScript values to GraphQL types, with `GraphQLID` for `id` and `*_id` names, `GraphQLInt` for integers, `GraphQLFloat` for other numbers, `GraphQLBoolean`, `GraphQLString`, `GraphQLList` for arrays, and a custom `DateType` for dates.

Relations and filters are conventions, not configuration

Two behaviours come for free from the shape of your data, and both are worth internalising because you will design your fixtures around them. The first is relations. For every field named `*_id`, the tool creates a two-way relationship so you can fetch related entities from both sides, so the presence of `user_id` in the `posts` entity gives you the related `User` for a `Post` and the related `Posts` for a `User`. The second is filtering. The `all*` queries accept parameters to sort, paginate and filter the list of results, and you can filter by any field rather than just the primary key, with a full-text query field named `q`, range filter fields for numeric and date fields, and a not-equal filter for all types except booleans and arrays. The generated `*Filter` type spells out the whole set, in the example a `PostFilter` with `q`, `id`, `id_neq`, `title`, `title_neq`, `views`, `views_lt`, `views_lte`, `views_gt`, `views_gte`, `views_neq`, `user_id` and `user_id_neq`. The result is a mock with a query surface close enough to a real API that a frontend written against it usually needs no changes, which is the entire point of the exercise.

Querying it, and the GraphiQL console you get for free

The server accepts queries in GET and POST, and under the hood it uses the `graphql-http` module, so the README points you at that project's documentation for details about passing variables and similar. A query against the example data looks like a normal GraphQL document, and the response comes back with the entity nested by relation, including a Date rendered in ISO form.

graphql
{
    Post(id: 1) {
        id
        title
        views
        User {
            name
        }
        Comments {
            date
            body
        }
    }
}

You can paste that into a URL, but you do not have to. The server is GraphiQL enabled, so browsing to the root of the server gives you a full featured graphical user interface with autosuggest and history, which turns the tool into a place where you can explore the generated schema interactively rather than reading the SDL. For a team learning GraphQL, that is the part that matters, because the schema is the thing you are learning, and seeing the introspection output and the auto-completion for filters and relations is a faster way to grasp it than reading a schema file. The same interface is what you point a frontend developer at when they need to know what the mock exposes.

Packaging, builds and the project tooling

The npm package is an ES module package with two entry points, the main one and a `./node` subpath, each shipping both an import and a require build along with type declarations, and the build script produces four artifacts, an ESM and CommonJS bundle, a node build, a UMD build and the TypeScript declarations, with vite configurations for the bundles and tsc for the declarations. The published files are the documentation, `dist`, `src` and `bin`, so the sources ship with the package, which is helpful when you want to read the implementation or patch it. The tooling is modern and small: biome for checking, formatting and linting, vitest with `supertest` for the tests, lint-staged with husky for the pre-commit hook, and a Makefile whose targets wrap the npm scripts, including an `install` target that also installs the example project, a `run` target that starts the server with the example data and a `check` target. The example directory with a browser example and a node example is the fastest way to see how the tool is meant to be embedded, since the browser example shows the UMD build in use and the node example shows the server entry point.

What this tool deliberately is not

The gaps are the obvious ones, and the README is not interested in filling them, which is fair for a mocking tool. There is no authentication, no authorisation and no per-entity validation, and the mutation payloads are typed as a plain `String` in the generated schema, so the data you send back is yours to shape. There is no documented persistence layer, so state lives in the running process, which is exactly what you want in a test and exactly what you do not want in a service. There is no schema-first workflow, since the schema is derived, and that cuts both ways: it is a fast path to a working mock and a slow path to a schema you can evolve deliberately. And the type inference means your fixtures are, in effect, your schema, so a fixture that happens to omit a field changes the contract your application sees. None of that is a criticism of a tool that describes itself as a testing and mocking utility with zero coding, but it is the reason the tool should stay in your test suite and out of your production path.

Editorial conclusion

Adopt json-graphql-server when you are building a frontend against a GraphQL API that does not exist yet, or when you want a stable mock for tests, because the schema it generates is derived from real data rather than from a hand written SDL, so the shapes match what your fixtures contain. Do not adopt it as a production backend, because it is explicitly a testing and mocking tool, and the README documents no persistence, authentication or validation. Before you rely on it, read the type inference rules, since nullability and field types are decided by the values present across your data, which means adding a record can change your schema, and check the filter and relation conventions, because the `_id` suffix and the `q` field are conventions rather than configuration. The licence is MIT, the current release is 3.3.2 from 2026-09-14, and the last push was on 2026-10-13.

Frequently asked questions

How do I run json-graphql-server?

Create a `db.js` file that exports an object whose keys are entity types and whose values are arrays of objects with at least an `id` key, then run `npx json-graphql-server db.js`, which serves on localhost port 3000. Use `--port` or `-p` for a different port and `--host` or `-h` for a different host.

How does json-graphql-server decide the GraphQL types?

The type of every field is inferred from the values in your data, so `Post.title` becomes a `String!` and `Post.views` an `Int!`. A field is made non nullable when all entities have a value for it, and every entity is expected to have an `id` field that is unique for its type, treated as the primary key.

Does json-graphql-server support relations and filtering?

Yes. Every field named `*_id` creates a two-way relationship, so `user_id` on a post gives you the related User and the related Posts. The list queries take paging, sorting and filter arguments, with a full-text `q` field, range filters for numeric and date fields, and not-equal filters for all types except booleans and arrays.

Can I browse the generated schema?

Yes. The server is GraphiQL enabled, so browsing to the root of the server gives you a graphical user interface with autosuggest and history. Queries are accepted in both GET and POST, handled through the graphql-http module.

How do I add json-graphql-server to a project?

Run `npm install -D json-graphql-server`, which is the development dependency form the README uses. The package ships a main entry point and a `./node` subpath, with ESM, CommonJS, UMD and type declaration builds.

Official sources

  1. Issues
  2. License: MIT
  3. marmelab/json-graphql-server on GitHub
  4. README
  5. Releases

Was this useful?