The Neo4j GraphQL library turns a graph schema into a GraphQL API
A GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations.
At a glance
- What is it?
- The neo4j/graphql repository is a TypeScript monorepo holding the official Neo4j GraphQL library, which generates a GraphQL schema from a Neo4j data model and translates GraphQL queries into Cypher, alongside a schema introspector and the GraphQL Toolbox. It is Apache-2.0 licensed, published as @neo4j/graphql, and released through Changesets on a dev branch.
- Who is it for?
- Neo4j GraphQL suits a team that wants to expose an existing Neo4j graph through GraphQL without hand-writing resolvers and Cypher for every query, since the library derives the schema from the data model and translates the queries, and the companion introspector generates a schema from a database that already exists.
- Can I use it commercially?
- Yes. Apache-2.0 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 1 day 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 October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the repository contains
The repository is described as a GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations, and the README calls it the Monorepo for Neo4j plus GraphQL.
Three packages matter, and the README names each one with the job it does.
The first is @neo4j/graphql, described as familiar GraphQL generation, for usage with an API such as Apollo Server. That is the library most people mean when they say Neo4j GraphQL. It takes a description of your graph and produces a GraphQL schema, then translates incoming GraphQL queries into Cypher so the database does the work.
The second is @neo4j/introspector, for introspecting schema from an existing Neo4j database. This is the package that solves the adoption problem, because a database that has been in production for two years has a schema nobody wants to retype by hand, and the introspector reads the live database and produces the type definitions the library needs.
The third is @neo4j/graphql-toolbox, a separate project for experimenting with your Neo4j GraphQL API on Neo4j. It is a GraphQL IDE pointed at your database, and it is the fastest way to see what the generated schema actually looks like and to try queries against real data before any application code exists.
The top-level entries show a full monorepo around those packages. There is a packages/ directory, an examples/ directory referenced from the README, a docs/ folder with a contributing and development guide, a docker-compose.yaml for local Neo4j, a .changeset/ directory, and renovate.json for dependency updates. The root package.json is private and marked as a workspace root with [email protected] as the package manager.
The primary language is TypeScript, the licence is Apache-2.0, and the last push was on 2026-10-20 with the latest published package version @neo4j/graphql 7.6.4 from 2026-10-12.
The monorepo tooling, and the dev branch
The repository is a TypeScript Monorepo managed with Yarn Workspaces, and the root package.json shows the shape of that setup.
The workspaces list covers packages/*, packages/graphql/tests/performance/server, examples/neo-place, and examples/subscriptions/*. That last entry is worth pausing on. The performance test server and the example applications are workspaces, which means they are versioned and built alongside the library rather than being scripts that live outside it. It is the arrangement that keeps an example from silently drifting away from the API it demonstrates.
The scripts show how a release happens. The build is tsc --build tsconfig.production.json, and the release scripts are yarn build followed by changeset publish, with three variants that differ only in the tag: release-dev publishes without a tag, release-lts publishes with the tag lts, and release-previous publishes with the tag previous.
Those three tags are the mechanism for a library that has to serve several kinds of consumer at once. The current line is published untagged, a long term supported line is published under lts for the users who cannot move every time the library releases, and a previous line is kept alive under previous for the users who are not ready to move yet. For a package that sits between an application and a database, that kind of channel structure is close to mandatory.
The build uses a separate tsconfig.production.json alongside the base and the default one, which is the standard way to keep the type checking that tests rely on different from the emit that consumers get.
The linting and test setup is a conventional one: eslint with a cache, jest for tests, prettier for formatting, ts-jest for the TypeScript transform, and a jest.config.base.js with a jest.config.js and a jest.global-setup.js on top of it.
Running the tests against a real Neo4j
Because the library translates GraphQL into Cypher and runs it, the test suite needs an actual database, and the docker-compose.yaml in the repository root is how that is provided.
neo4j-service:
image: neo4j:5.7.0-enterprise
ports:
- 7474:7474
- 7687:7687
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_AUTH=neo4j/NeedsALongPassword
- NEO4J_PLUGINS=["apoc"]The composition is a Neo4j 5.7.0 Enterprise instance with the HTTP port 7474 and the Bolt port 7687 published, the licence acceptance environment variable set, and the credentials in the same file. The plugins list includes apoc, which is Neo4j's procedure library, and its presence tells you the tests exercise Cypher features beyond the core language.
The healthcheck is what makes the second service work, and it is a small detail that shows care:
healthcheck:
test: wget http://localhost:7474/browser -O -
interval: 1s
timeout: 1s
retries: 40A one second interval with forty retries gives the container up to forty seconds to come up, and the tests service depends on the neo4j-service with the condition service_healthy rather than merely service_started. Starting the test container before the database is accepting connections produces failures that look like test bugs, and the healthcheck plus the depends_on condition is how that is avoided.
The tests service itself is built from the repository context and inherits the connection details through the environment, with NEO_URL pointing at the Bolt URL of the other service and NEO_USER and NEO_PASSWORD carrying the credentials.
Contributing, and where the documentation lives
The contributing guidance is short and specific about one thing that catches people out.
The default branch for this repository is dev, which contains changes for the next release. This is what you should base your work on if you want to make changes.
That is worth internalising before opening a pull request. A repository whose default branch is the development branch rather than the released one means the released versions are cut from somewhere else, and a pull request based on a release branch will conflict with the direction the project is taking.
The README points at a contributing guide at CONTRIBUTING.md and a development guide at docs/contributing/DEVELOPING.md, and says to visit the Contributing Guide to learn how to set up, test and contribute to Neo4j GraphQL.
The documentation for users is separate from the documentation for contributors. The manual is at neo4j.com/docs/graphql-manual/current/, and there is a hands-on course on GraphAcademy for the fundamentals of GraphQL and how to use the Toolbox and the library to create Neo4j-backed GraphQL APIs. The course is the efficient path for someone who has not used GraphQL before, because the library assumes you already know what a GraphQL schema and a query are.
For the people who already know GraphQL, the community channels are the main route. There is a Discord server and a Discourse category on the Neo4j community site under drivers and stacks, GraphQL, and the README also points at the media list, which includes a talk on best practices for using Cypher with GraphQL and one on securing your graph with Neo4j GraphQL.
The hosted option: GraphQL for AuraDB
The README carries a section on GraphQL for Neo4j AuraDBs, and it is a separate thing from the library, which is worth separating clearly.
The announcement describes a GraphQL API for Neo4j AuraDB that combines the graph database with GraphQL's data access capabilities. The stated benefits for developers are creating precisely tailored queries that return only needed data, reducing over-fetching and under-fetching, building more responsive applications with fewer round trips, and leveraging declarative data fetching while maintaining the power of graph relationships.
The availability is stated narrowly: it is available now for AuraDB Professional Trials, AuraDB Professional, and AuraDB Business Critical, with support for AuraDB Virtual Dedicated Cloud coming soon.
That tiering is the practical detail. If you are on AuraDB Free, or on a self-managed Neo4j instance, the hosted GraphQL API is not what you have, and the library in this repository is the route instead. It is also worth noticing what the announcement claims to solve: over-fetching and under-fetching are the classic GraphQL-versus-REST argument, and the fact that a graph database vendor is pitching them is an endorsement of the API style rather than of a particular implementation.
The release history of the library itself is steady: @neo4j/graphql 7.6.4 from 2026-10-12, 7.6.3 from 2026-09-02 and 7.6.2 from 2026-08-27. Patch releases roughly monthly, which is what a library that sits under an application and above a database should look like.
Where the Neo4j GraphQL library fits, and where it stops
The comparison worth making is with writing resolvers by hand and with a general purpose GraphQL server over a relational database.
Against hand-written resolvers, the difference is the amount of code you own. Every node type, every relationship and every filter becomes a resolver and a Cypher query that you maintain, and the queries drift apart in style and in performance. The library derives the schema from the graph model and generates the Cypher, so the surface of your API follows the shape of your data rather than the shape of your resolvers.
The introspector makes that derivation practical for existing databases, which is the difference between this being usable for a new project and this being usable for a project with a database that has been running for years.
Against a general GraphQL server over a relational database, the difference is what the query planner gets to work with. A relational GraphQL layer resolves a nested selection into SQL joins, which gets expensive quickly for a deep selection over a wide schema. A graph database resolves it as a traversal, and the Neo4j GraphQL library is designed around that. That is the argument for the whole approach, and it holds when your data is genuinely relational in the graph sense.
The limits are worth stating. The schema is derived, so if your API should not look like your graph, the library is fighting you and you will end up writing resolvers anyway for the parts that differ. The generated schema is large for a big graph, which has consequences for tooling and for the client side. And the whole approach depends on the client being able to issue the queries efficiently, which is why the Cypher best practices talk in the media list is not optional reading.
There is also the version question. The library is at version 7, and the media list includes a talk titled Migrating To The Official Neo4j GraphQL Library and an announcement of the stable release of version 1.0.0, which tells you that the package has been through at least one significant reorganisation of its API. A team picking it up now starts from the current major version, but code written against earlier versions will need attention.
For the record on maintenance: the last push was on 2026-10-20 and the repository is not archived, the licence is Apache-2.0 in both the root package.json and the LICENSE.txt at the root, and the package is published under the @neo4j scope on npm.
Editorial conclusion
Neo4j GraphQL suits a team that wants to expose an existing Neo4j graph through GraphQL without hand-writing resolvers and Cypher for every query, since the library derives the schema from the data model and translates the queries, and the companion introspector generates a schema from a database that already exists. It is the wrong tool if you need the shape of the API to differ substantially from the shape of the graph, because the mapping is derived rather than designed, and it is the wrong tool if you are not running Neo4j. Before adopting it, read the contributing guide and the development guide, and check the current release on npm, since the repository's default branch is dev and carries changes for the next release.
Frequently asked questions
What is the Neo4j GraphQL library?
It is a GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations. The @neo4j/graphql package generates a GraphQL schema from a Neo4j data model and translates GraphQL queries into Cypher, and it is intended to be used with an API such as Apollo Server.
What packages does the neo4j/graphql monorepo contain?
Three that matter: @neo4j/graphql for GraphQL generation, @neo4j/introspector to introspect a schema from an existing Neo4j database, and @neo4j/graphql-toolbox, a separate project for experimenting with a Neo4j GraphQL API. The monorepo is a Yarn Workspaces TypeScript project that also includes example applications as workspaces.
How do I run the Neo4j GraphQL library tests?
The repository ships a docker-compose.yaml that starts a neo4j:5.7.0-enterprise service with the HTTP port 7474 and the Bolt port 7687, the apoc plugin, and a healthcheck, plus a tests service that depends on it with the condition service_healthy and connects through NEO_URL, NEO_USER and NEO_PASSWORD. The test command is jest.
Which branch should I base a pull request on?
The dev branch, which is the default branch and contains changes for the next release. The README says explicitly that this is what you should base your work on if you want to make changes, and points at CONTRIBUTING.md and docs/contributing/DEVELOPING.md for setup, testing and contribution guidance.
How are releases published for the Neo4j GraphQL library?
Through Changesets. The root package.json has three release scripts that build and then publish with changeset publish, differing only in the distribution tag: release-dev publishes untagged, release-lts publishes under the lts tag, and release-previous publishes under the previous tag, so several versions can be maintained at once.
Is there a hosted GraphQL API for Neo4j?
Yes, GraphQL for Neo4j AuraDB, which Neo4j describes as combining the graph database with GraphQL's data access capabilities, promising fewer round trips and less over-fetching and under-fetching. It is available for AuraDB Professional Trials, AuraDB Professional and AuraDB Business Critical, with support for AuraDB Virtual Dedicated Cloud described as coming soon.
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/neo4j-graphql)Was this useful?