graphql-js: the reference implementation behind most JavaScript GraphQL stacks
A reference implementation of GraphQL for JavaScript
At a glance
- What is it?
- GraphQL.js is the MIT-licensed JavaScript reference implementation of the GraphQL specification, maintained by the GraphQL Foundation. It gives you a schema builder and a query executor, not a server, a client, or a database.
- Who is it for?
- Adopt GraphQL.js when you need to build a schema and execute queries in Node or the browser, and you want the implementation that the GraphQL specification itself is tested against. Do not adopt it expecting a server, a client cache, or a database layer: the README describes two capabilities, building a type schema and serving queries against it, and nothing else.
- 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 last received commits 2 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What GraphQL.js actually is, and who reaches for it
GraphQL.js is a library, not a service. The README describes exactly two capabilities: building a type schema, and serving queries against that type schema. Everything else that people associate with GraphQL in JavaScript, the HTTP endpoint, the query editor, the client-side cache, lives in other projects.
That narrowness is the point. If you are writing a resolver layer, a schema-first gateway, a code generator, or a test harness that needs to parse and validate GraphQL documents, you want the parser and validator that the specification's own reference tests exercise. If you want a running server with a playground attached, this is one layer below what you are looking for.
The audience is therefore fairly specific: backend engineers defining a schema in code, tooling authors who need spec-compliant parsing and validation, and anyone building on top of the library rather than beside it. The README points to GraphiQL as an example of a tool built with GraphQL.js, which is a fair illustration of the level this sits at.
Schema construction and execution: the two moving parts
The mechanism is small enough to state plainly. You construct a GraphQLSchema from type definitions, where each field carries a type and an optional resolve function. The resolve function is where your application code runs, and the README notes it can return a value, a promise, or an array of promises. That promise handling is what makes the executor usable against databases and remote services without a separate async layer.
Execution goes through the exported graphql function, which takes a schema and a source document. The README is explicit about ordering: the function first ensures the query is syntactically and semantically valid before executing it, and reports errors otherwise. So validation is not something you opt into; it happens on every call. The example error output shows a message and a locations array with line and column, which is what you would surface to a client or a developer tool.
The distribution matters too. GraphQL.js ships both CommonJS and ESModule builds, with the exports map in package.json directing runtimes and bundlers to the right files. Bundlers that understand exports will include only the portions you use. Tools that do not support exports fall back to side-by-side files, CommonJS in .js and ESModule in .mjs. The package is marked sideEffects: false, which is what lets tree shaking work in the first place.
Installing GraphQL.js and running a first query
Installation is a single npm command. The README lists npm, yarn and bun variants; the npm one is the common case.
npm install --save graphqlAfter that, the smallest useful program builds a schema with one field and executes a query against it. This is the README's example, and it is worth typing out rather than skimming, because the shape of the resolve function is the thing you will repeat for every field in a real schema.
import {
graphql,
GraphQLSchema,
GraphQLObjectType,
GraphQLString,
} from 'graphql';
var schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'RootQueryType',
fields: {
hello: {
type: GraphQLString,
resolve() {
return 'world';
},
},
},
}),
});Then execute a document against that schema. The result object carries data on success and errors on failure, and the README shows both shapes.
var source = '{ hello }';
graphql({ schema, source }).then((result) => {
console.log(result);
});Querying a field that does not exist produces an errors array rather than a thrown exception, with the message naming the field and the parent type and locations giving the line and column. That distinction between returned errors and thrown exceptions is worth internalizing early, because it determines how you write your own error handling around the call.
Runtime requirements and the bleeding-edge npm branch
The engines field in package.json requires Node ^22.0.0, ^24.0.0, ^25.0.0 or >=26.0.0. Note the gaps: Node 23 is not in that list. If your deployment is pinned to an odd-numbered Node release, check this before you plan an upgrade, because it is a hard constraint declared by the package rather than a soft recommendation.
The repository also exposes an npm branch, which the README says is automatically maintained to be the last commit to 17.x.x that passes all tests, in the same form found on npm. You can depend on it directly:
npm install graphql@git://github.com/graphql/graphql-js.git#npmThe README recommends the published npm builds for many reasons and frames the branch as something for people who want the latest not-yet-released version. Treat that literally. A branch that tracks the last passing commit is a moving target, and nothing in the README promises it will not move under you between installs.
Where GraphQL.js is the wrong layer
The most common mismatch is expecting a server. GraphQL.js has no HTTP transport, no routing, no middleware, and no query editor. The README's own framing, two capabilities, building a schema and serving queries against it, should be read as the complete scope. If you need an HTTP endpoint, you are choosing a transport layer in addition to this library, and that choice is outside what the README covers.
A second mismatch is expecting a database interface. GraphQL.js does not know where your data lives. Every field's resolve function is yours to write, and the executor's job ends at calling it and assembling the response. Teams that want schema-to-database mapping are looking at a different category of tool.
A third, subtler one: the graphql function validates on every call. For a high-volume endpoint where the same document arrives thousands of times a second, that is work you may want to do once and cache rather than repeat. The README does not discuss document caching or persisted queries, so if that is your requirement you are designing it yourself on top of the parsing and validation primitives.
Finally, the version support policy is worth reading before you pin a major. The latest major gets full support including bug fixes and security updates. The previous major gets feature support for 12 months after the newest major ships, with bug and security fixes continuing. Anything older is unsupported, with one exception: a version released less than a year ago is treated as the previous major. There is no LTS release, and the README says so directly.
GraphQL.js compared with Apollo Server
The comparison people actually search for is graphql-js versus Apollo, and the difference is one of scope rather than quality. Apollo Server is a server: it takes an HTTP request, wires in a schema, and returns a response, with its own opinions about context, plugins, and lifecycle. GraphQL.js is the schema and execution engine that a server like that sits on top of.
That means the two are not really substitutes. If you adopt Apollo Server, you are almost certainly still running GraphQL.js underneath, or a compatible implementation of the same specification. If you adopt GraphQL.js alone, you are writing the HTTP handling yourself.
The practical split: choose GraphQL.js when you want control over the transport, when you are building tooling rather than a service, or when you want the reference implementation specifically. Choose a full server framework when you want the request lifecycle handled for you and you are willing to accept its conventions. The README's description of GraphiQL as a tool built with GraphQL.js is a good example of the first case.
Maintenance, licensing and what an upgrade costs
The repository is not archived, and the last push was on 2026-09-17. Releases are tracked as GitHub releases, and the recent list includes v15.10.3 on 2026-08-28 alongside v17.0.1 and v17.0.2 in June and July 2026. That pattern, a 15.x patch landing after 17.x releases, is consistent with the stated policy of continuing bug and security fixes on the previous major while the current major moves forward.
The licence is MIT, stated in both the README and package.json. That is permissive and imposes no copyleft obligation on your own code. This is a statement about what the repository declares, not legal advice; if your organisation has specific compliance requirements, the LICENSE file is the thing to read.
Upgrade cost is where the policy bites. The README says detailed release notes are maintained for each version, highlighting new features, breaking changes and deprecations, and that documentation includes migration guides for moving between major versions. So the upgrade path is documented rather than improvised. The absence of an LTS release means you cannot park on an old major and expect indefinite security fixes: after the EOL date, which is announced at least 6 months in advance, a version receives no updates even for critical security issues. Budget for major-version upgrades as a recurring cost rather than a one-off.
Editorial conclusion
Adopt GraphQL.js when you need to build a schema and execute queries in Node or the browser, and you want the implementation that the GraphQL specification itself is tested against. Do not adopt it expecting a server, a client cache, or a database layer: the README describes two capabilities, building a type schema and serving queries against it, and nothing else. Before you commit, check the engines field against your runtime, since package.json requires Node ^22.0.0, ^24.0.0, ^25.0.0 or >=26.0.0, and read the version support policy if you are staying on a previous major.
Frequently asked questions
What is GraphQL and why use it?
The README frames GraphQL as a query language for APIs, and GraphQL.js as its JavaScript reference implementation. In practice the library gives you two things: a way to build a type schema that maps to your codebase, and a way to serve queries against that schema.
Is GraphQL better than a REST API?
The README does not compare GraphQL with REST, so it offers no basis for that judgement. What it does describe is a query language and a runtime, with the graphql function validating a document before executing it against a schema.
Is GraphQL still relevant in 2026?
The repository is not archived, and its last push was on 2026-09-17, with v15.10.3 released on 2026-08-28 and v17.0.2 on 2026-07-03. The README states that no LTS version is offered and that users are encouraged to upgrade to the latest stable version.
Is GraphQL just HTTP?
No. GraphQL.js itself has no HTTP transport; the README describes building a type schema and serving queries against it, and the execution entry point is the graphql function taking a schema and a source document. Any HTTP layer sits outside this library.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/graphql-graphql-js)