Cosmo: a self-hostable control plane for GraphQL Federation
The open-source solution to building, maintaining, and collaborating on GraphQL Federation at Scale. The alternative to Apollo Studio and GraphOS.
At a glance
- What is it?
- WunderGraph Cosmo is an Apache 2.0 platform for federated GraphQL that covers the whole lifecycle, from schema registry and composition checks through analytics, metrics, tracing, and routing. The interesting part is that the router, the control plane, and the CLI are separately versioned releases, so you can pin the data plane independently of the management plane.
- Who is it for?
- Adopt Cosmo if you run a federated GraphQL estate and want composition checks, analytics, and routing under your own control instead of a hosted platform. Do not adopt it for a single monolithic schema, since the whole value is in composition and routing across subgraphs.
- 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 received new commits within the last day.
- 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 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the platform covers
WunderGraph Cosmo is described as a comprehensive Lifecycle API Management platform tailored for Federated GraphQL. It encompasses everything from Schema Registry, composition checks, and analytics, to metrics, tracing, and routing.
That list is the product definition, and the word Lifecycle is doing the work. A federation setup has more moving parts than a GraphQL server: a registry of subgraph schemas, a composition step that checks whether they can be combined, a router that serves the composed graph, and a way to see what the router is actually doing. Cosmo covers each of those, and the platform is positioned as the alternative to Apollo Studio and GraphOS.
The deployment story is deliberately flexible. Whether you are looking to deploy 100% on-premises or prefer a managed service at cosmo.wundergraph.com, Cosmo offers flexibility without vendor lock-in, all under the Apache 2.0 license. The self-hosted option is not a stripped-down tier, and that is the point of the open source licence, since a control plane that holds your schema registry and your traffic analytics is exactly the kind of component most teams will not hand to a vendor.
The project is written in TypeScript and Go together, the primary language is listed as TypeScript, the default branch is main, and the last push to the repository was on 2026-10-15. The recent releases are three different packages published the same day, [email protected], [email protected], and [email protected], which tells you the platform is a set of independently versioned components rather than one binary.
The three components, versioned separately
The release list is the clearest description of the architecture, because it names the components and shows that each one moves on its own schedule.
The router is the data plane component, and the topics list it with apollo-federation, graphql-router, and gateway, which reflects that it implements the Apollo Federation specification and can sit in front of an existing setup. The control plane is the management component, and it is where the registry, composition, and configuration live. And graphqlmetrics is the observability piece, which is the component that collects and stores the telemetry.
Having the router and the control plane on separate version lines is a deliberate property rather than a packaging accident. The router is the thing in your request path, and you upgrade it when you want to, under your own schedule. The control plane is the thing you interact with, and it can move faster. A team that pins the router at a known good version and lets the control plane track the latest is a normal deployment pattern, and it is only possible because the two are decoupled.
The graphqlmetrics component is what the observability blog post describes as the architecture of the WunderGraph observability stack, and there is a separate post on how they scaled the router for the SuperBowl, which is a useful signal about the traffic the design targets.
The topics also list apollo and apollo-federation, which is worth reading carefully. Cosmo is an alternative to Apollo Studio and GraphOS, but it implements the Apollo Federation specification, so the schemas and composition rules are the ones your subgraphs already use.
Four ways in, one per role
The Try Cosmo Now section is structured by the role you are playing rather than by feature, and most entries point at a different example in the repository, which is a neat way to scope a large platform down to something you can evaluate in an afternoon.
The Developer path is the router-simple example, which starts by composing a federated GraphQL schema locally from multiple services and running the Cosmo Router. The Architect path is the full-cosmo-docker example, which evaluates the entire platform for an organisation by running it locally with Docker Compose. The Platform Engineer path is the full-cosmo-helm example, which deploys the whole platform to Kubernetes through the official Helm Chart. And the Decision Maker path, for an engineering manager or a CTO, is a contact link rather than an example, since that conversation is about organisational fit rather than a running system.
That progression is a sensible teaching order. The router alone is a single binary you can point at two subgraphs, and if the value is not there, the rest of the platform is not going to convince anyone either. The Docker Compose stack is the full local evaluation, and the Helm chart is the production shape.
The Getting Started section is the short version of the same thing: clone the repository with git clone https://github.com/wundergraph/cosmo.git, choose the example that fits your role from the section, and follow its instructions, then read the docs for the rest.
The local stack, and what the compose file needs
The compose file in the repository is the dev stack, and it names the dependencies precisely.
Postgres is the first, on the dev profile, with an init.sql mounted into the entrypoint init directory and the data directory on a named volume, and the image version pinned through a DC_POSTGRESQL_VERSION variable defaulting to 15.3. The database name defaults to controlplane, which tells you the control plane is the component that owns the schema registry.
Keycloak is the second, on a purpose-built image under ghcr.io/wundergraph/cosmo, started with --import-realm --optimized, with a realm.json mounted read-only from the docker/keycloak directory, and with health and metrics enabled. A Keycloak realm file being mounted read-only is the detail that matters, since it means the dev identity setup is a file in the repository rather than something you click through.
Jaeger is the third, and it carries a comment that says it is only there to test OTEL instrumentation. It is on its own debug profile rather than the dev profile, which is a tidy way of saying the observability path is optional in local development even though it is not optional in production.
The Makefile has matching targets for each profile, with infra-up, infra-build, infra-restart, and separate up and down commands for the edfs profile, which is the event driven federation stack, plus separate debug targets that also pass the -v flag to remove named volumes.
The prerequisite target is also revealing. It prints go version, pnpm -v, node -v, docker -v, dbmate -v, mockery version, and testifylint -V=full, so the toolchain is Go, pnpm, Node, Docker, the dbmate migration tool, mockery for mocks, and testifylint for the test assertions.
The toolchain, and a monorepo that spans three languages
The root package.json is a pnpm and Lerna workspace, and the scripts describe a repository that is not only TypeScript.
The build is pnpm -r run build and the tests run in parallel with pnpm run -r --parallel test. The interesting part is the code generation, which is protobuf and Connect based. The generate script runs pnpm buf generate over several proto paths, covering the platform, notifications, common, node, and ai packages, and then builds the connect package. There is a second generator, generate:ptq, that pulls protos from the yoko repository over ssh with a pinned ref, which is how the platform's service protocol stays in step with another repository.
The Go side is set up with a Makefile target that installs the build tools, pinned to exact versions: buf at v1.32.2, protoc-gen-go at v1.36.11, protoc-gen-connect-go at v1.19.1, and gotestsum at v1.13.0. A second target adds the development tools, with dbmate at v2.6.0 for database migrations, kubeconform at v0.6.3 for validating Kubernetes manifests, helm-docs at v1.11.3 to generate the chart documentation, mockery at v3.3.1 to generate mocks, and testifylint at v1.6.1 to lint the test assertions.
The buf configuration files at the top level are the giveaway about the protocol layer. There is a buf.yaml plus per-language generate templates, buf.ts.gen.yaml for the TypeScript output and buf.router.go.gen.yaml for the Go router, along with buf.connect-go.go.gen.yaml, buf.graphqlmetrics.go.gen.yaml, and buf.ptq.gen.yaml. Connect is the RPC layer between the control plane and the router, and it is why the two are separately versioned and separately buildable.
The engines field pins node at 22.22.2 and pnpm at 11, and the devEngines block repeats the Node requirement with an onFail of download, so a contributor with the wrong Node version is fixed rather than confused.
The repository layout, and what the adr directory is for
The top level of the repository is a map of the platform, and the directory names are the component names.
There is cli/ for the wgc command, since the root package.json declares a bin entry mapping wgc to the CLI build output. There is router/ for the data plane and controlplane/ for the management plane, and graphqlmetrics/ for the observability component, and each of those is a separately versioned release. There is composition/ for the composition checks, and connect/ and connect-go/ for the Connect RPC layer.
Then there are the services that surround them. The cdn-server/ is the component that serves the router configuration and the GraphQL API over HTTP, the admission-server/ is the component that validates incoming requests against the schema, and the aws-lambda-router/ is a variant of the router that runs as a Lambda function. There is a keycloak/ directory for the Keycloak image build, and a demo/ directory with its own Go module, its own Makefile, and several graph.yaml variants including a graph-with-plugin.yaml and a graph-with-standalone.yaml.
The directory that says the most about how the project is run is adr/, which is where architecture decision records live. A project of this size accumulates decisions about boundaries and protocols, and keeping them as files rather than in chat history is how a team avoids relitigating them.
The rest of the tree is the surrounding infrastructure: helm/ for the chart, infrastructure/ for the deployment definitions, docs-website/ and docs/ for the two documentation sets, otelcollector/ for the OpenTelemetry collector, client-tests/ for the end to end client tests, data_migrations/ for the schema changes over time, and mise-tasks/ for the task runner tasks. The Compose files come in three variants, a base one, a full one, and a Cosmo specific one, which is the usual shape for a platform that has a minimal, a complete, and a production-shaped local stack.
Editorial conclusion
Adopt Cosmo if you run a federated GraphQL estate and want composition checks, analytics, and routing under your own control instead of a hosted platform. Do not adopt it for a single monolithic schema, since the whole value is in composition and routing across subgraphs. Verify first how the router version relates to the control plane version, because the two are released independently and a mismatched pair is the most likely source of friction.
Frequently asked questions
What is WunderGraph Cosmo?
It is a comprehensive Lifecycle API Management platform tailored for Federated GraphQL, encompassing schema registry, composition checks, analytics, metrics, tracing, and routing. It is positioned as the open source alternative to Apollo Studio and GraphOS, licensed under Apache 2.0, and can be deployed fully on-premises or used as a managed service.
Which components does Cosmo release separately?
The router, the control plane, and graphqlmetrics are released as separate packages with their own version lines, so the recent release list shows [email protected], [email protected], and [email protected] published on the same day. The router is the data plane component and the control plane holds the registry and configuration.
How do I try Cosmo locally?
Clone the repository, then pick the example that matches your role. The Developer path composes a schema locally and runs the router, the Architect path runs the full platform with Docker Compose, and the Platform Engineer path deploys the whole platform to Kubernetes with the official Helm chart.
What does the Cosmo local development stack need?
Postgres, which is the control plane database, Keycloak started with an imported realm, and optionally Jaeger for testing OTEL instrumentation. The Makefile installs the build tools at pinned versions, including buf, protoc-gen-go, protoc-gen-connect-go, gotestsum, dbmate, kubeconform, helm-docs, mockery, and testifylint.
How is the Cosmo control plane and router wired together?
Through protobuf and Connect RPC, with the generate script running buf generate over the platform, notifications, common, node, and ai proto paths, and a second generator that pulls the platform service protocol protos from the yoko repository over ssh with a pinned ref. The Connect layer is why the two components are versioned independently.
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/wundergraph-cosmo)Was this useful?