Library / SDK
wundergraph/graphql-go-tools avatar
wundergraph/graphql-go-tools

graphql-go-tools is the Go engine under the Cosmo router, not a router itself

GraphQL Router / API Gateway framework written in Golang, focussing on correctness, extensibility, and high-performance. Supports Federation v1 & v2, Subscriptions & more.

837 stars171 forksGoMIT

At a glance

What is it?
graphql-go-tools is a multi package Go library holding a GraphQL lexer, parser, AST, validation, normalization, query planner and resolver, with Federation support. The README itself points operators who want a finished gateway to Cosmo Router instead, and the v1 module line is retracted.
Who is it for?
graphql-go-tools v2 is the right dependency if you are writing Go code that has to parse, validate, normalize, plan or execute GraphQL, especially across a federated graph, and you want those pieces as a library rather than as a service. It is the wrong dependency if your goal is to run a gateway, because the README sends you to Cosmo Router for that and describes examples/federation as not production ready.
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 1 day ago.
What is it written in?
Mainly Go, 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

A library of GraphQL internals rather than a gateway you can run

The repository name says tools, and the README heading says framework, but the description is more precise: a GraphQL router and API gateway framework written in Golang, focused on correctness, extensibility and performance, supporting Federation v1 and v2 plus subscriptions. What you actually get when you depend on it is a set of Go packages.

The v2 package table describes the core as an engine implementation consisting of lexer, parser, AST, AST validation, AST normalization, datasources, query planner and resolver, with support for GraphQL Federation and built-in support for batching federation entity calls. Those are the layers a GraphQL server needs, and they are the layers this project maintains as a library.

Who that is for is fairly narrow. It suits a Go team that wants to embed GraphQL parsing and execution into a service it already owns, or that wants to control the plan and the resolver directly instead of delegating to a gateway process. The repository topic tags point the same way: ast, ast-parser, ast-printer, ast-transformation, ast-visitor, complexity-analysis, execution, introspection, introspection-query, lexer, linter, parser, printing and validation. These are the vocabulary of a toolchain, not of a hosted product.

The README is blunt about the boundary. Under the heading that calls this a replacement for Apollo Router, it tells you that if you want a complete ready to use open source router for Federation, you should look at Cosmo Router, which is based on this library.

Separate Go modules per package, joined by a go workspace

The repository is not one module. The README states that it contains multiple packages joined via a workspace, and the top level listing confirms a go.work and go.work.sum file next to the root go.mod, plus an execution directory, a v2 directory, examples and a docs directory.

The root go.mod declares the module as github.com/wundergraph/graphql-go-tools and then tells you to use github.com/wundergraph/graphql-go-tools/v2 instead. It also carries a retract block, which is how Go marks a version as unusable for resolution.

go
retract (
	[v1.0.0, v1.67.5]
	v0.13.2
	v0.0.1
)

The package table describes the v1 line as deprecated and retracted. That is a concrete upgrade cost for anyone arriving from an older tutorial or a pre v2 import. You change the import path, and the old path stops being a safe thing to depend on.

The other modules in the table have their own dependency lines. The execution package depends on graphql-go-tools v2 and on a composition module. The examples/federation module depends on the execution package. Each one carries its own go.mod, so a consumer picks the module boundary that matches what it needs rather than pulling the whole workspace.

The Go version requirement is not negotiable

The root go.mod sets a language version that sits at the top of what most toolchains ship.

go
go 1.26.0

That single directive decides whether the module will build in your environment at all, and it is worth checking before anything else. A team pinned to an older Go release cannot simply bump a dependency, because the module itself declares the newer language version. This is the sort of constraint that is easy to miss when the project is adopted as one line in a go.mod, and expensive to discover during a release.

The other signal of a modern toolchain is in the build and layout files. The repository carries a .golangci.yml configuration, an eslint and commitlint configuration for the JavaScript tooling around it, release-please configuration files for the release flow, and separate Go directories for the v2 engine, the execution helpers and the example gateway. There is also a tools directory and a docs directory.

No supported configuration for the query planner is set out anywhere in the project documentation, beyond the package description, so treat the language version and the module layout as the two facts you can rely on when planning the upgrade.

examples/federation is a demonstration, and the README says so

The example gateway is described as an example implementation of a GraphQL federation gateway, and the table adds the sentence that this example is not production ready, with a pointer to cosmo router for a production ready solution.

That warning is the most useful sentence in the README for anyone evaluating the project, because it draws the line between the two ways to deploy this code. One is to import the packages and build your own service, where you own the operational surface. The other is to run Cosmo Router, which wraps this library and ships the parts you would otherwise have to assemble: a federation gateway, OpenTelemetry metrics and distributed tracing, Prometheus metrics, a GraphQL schema usage exporter, health checks, a GraphQL playground, an execution tracing exporter with a UI in the playground, federated subscriptions over WebSockets with graphql-ws and graphql-transport-ws protocol support as well as SSE, authentication using JWKS and JWT, high availability and scalability using S3 as a backend for the router config, persisted operations or trusted documents, traffic shaping covering timeouts, retries, header and body size limits and subgraph header forwarding, and custom modules and middleware.

That list is the real difference between the library and the product. Nothing in the table above tells you the engine alone gives you a ready gateway.

From parsing to planning, the layers are separable

Because the packages are separate, you can adopt one layer without the rest. The execution package is described as holding execution helpers for the request handling and engine configuration builder, and it is also where the important integration tests live. That is a hint about how the project wants to be used: the engine is configurable through a builder rather than only through the top level API.

The topic tags describe the shape of the internals in more detail than the README prose does. There are ast-normalization, ast-transformation and ast-visitor tags, plus ast-printer and printing. A visitor based transformation model is what lets the engine rewrite a query document, and normalization is the step where equivalent query shapes are collapsed before planning. The project publishes a blog post titled How Normalization affects Query Planning, and another on an algorithm to minify GraphQL ASTs, which tells you the AST layer is treated as a first class concern rather than a parser side effect.

Subscriptions are supported, and the repository has posts on federated subscriptions with NATS, on using Epoll and Kqueue to scale GraphQL subscriptions in Go, and on a Dataloader 3.0 breadth first data loading algorithm for federation data loading. Read these as design context rather than as guarantees: the code in this repository is the library, and the operational shaping of subscriptions belongs to the router built on top of it.

Release cadence is fast and the major version line moved once

Maintenance state comes straight from the release list and the last push date. Version v2.29.0 was released on 2026-10-19, v2.28.0 and v2.27.0 both on 2026-10-07, and the last push to the repository was on 2026-10-19. The package table marks the v2 engine as the actual version with active development, the execution package as the actual version, and the v1 line as deprecated and retracted.

Two releases inside a single day, and a tagged release on the same day as the last push, means the project ships often. That cuts both ways. You get fixes quickly, but a dependency pinned to a v2 minor can move under you, and the retract block shows the project is willing to declare a whole range of versions unusable when the import path changes.

The licence is MIT, with the LICENSE file at the repository root. Read that file for the exact terms if you plan to embed the engine in a commercial product. Nothing in the README describes a support policy or a compatibility promise between v2 minor versions, so if you need one, ask the maintainers rather than inferring it from the release cadence.

Editorial conclusion

graphql-go-tools v2 is the right dependency if you are writing Go code that has to parse, validate, normalize, plan or execute GraphQL, especially across a federated graph, and you want those pieces as a library rather than as a service. It is the wrong dependency if your goal is to run a gateway, because the README sends you to Cosmo Router for that and describes examples/federation as not production ready. Before adopting it, confirm your Go toolchain matches the go 1.26.0 directive in go.mod, import the v2 module path rather than the retracted root path, and read the package table in the README to see which module you actually need, since execution and examples/federation are separate Go modules with their own dependency lines.

Frequently asked questions

What is graphql-go-tools used for?

It is a set of Go packages that implement GraphQL engine internals: lexer, parser, AST, AST validation, AST normalization, datasources, query planner and resolver, with support for GraphQL Federation and batching of federation entity calls. It is a library you embed, not a gateway process you run.

Is graphql-go-tools an alternative to Apollo Router?

The README describes it as a replacement for Apollo Router but points you to Cosmo Router when you want a complete ready to use open source router for Federation, since Cosmo Router is built on this library. The repository also notes that the federation example in examples/federation is not production ready.

What happened to the v1 version of graphql-go-tools?

The v1 line is described as deprecated and retracted, and the root go.mod retracts the version range v1.0.0 through v1.67.5 along with v0.13.2 and v0.0.1. New work should use the v2 module path github.com/wundergraph/graphql-go-tools/v2.

What Go version does graphql-go-tools need?

The root go.mod declares go 1.26.0. If your toolchain is older, the module will not build until you upgrade Go, so check that directive before planning the dependency upgrade.

How do I add graphql-go-tools to a Go project?

The repository is split into separate Go modules joined by a go workspace, and the README tells you to use github.com/wundergraph/graphql-go-tools/v2 rather than the root module path. Pick the module you need, either the v2 engine, the execution helpers, or the federation example, and depend on that module path.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. wundergraph/graphql-go-tools on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/wundergraph-graphql-go-tools.svg)](https://hysenlabs.com/projects/wundergraph-graphql-go-tools)

Was this useful?