CLI tool
cloudflare/workers-graphql-server avatar
cloudflare/workers-graphql-server

workers-graphql-server puts an Apollo GraphQL API on Cloudflare Workers

🔥Lightning-fast, globally distributed Apollo GraphQL server, deployed at the edge using Cloudflare Workers

793 stars554 forksTypeScriptLicense varies

At a glance

What is it?
workers-graphql-server is a TypeScript template that runs an Apollo GraphQL server inside a Cloudflare Worker, with schema code generation, KV caching and Hono for the HTTP layer. It is a starting point with a PokeAPI example, and it was last pushed on 2026-04-23.
Who is it for?
workers-graphql-server suits a team that wants a read-heavy GraphQL API served close to its users without running a Node server, since the Worker runtime handles the request path and the KV cache sits right inside the resolvers. It is the wrong starting point if you need long running queries, mutations with heavy database work, or a GraphQL API that must live inside an existing Node deployment.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months 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

An Apollo server that runs at the edge

workers-graphql-server is an Apollo GraphQL server built with Cloudflare Workers, written in TypeScript. The pitch is that whether you host your APIs on-premises, in the cloud, or you are deploying databases to Cloudflare directly, you can deploy a globally distributed GraphQL server with Cloudflare Workers.

The project structure says it is a template rather than a library. The source shows how to make requests to external APIs, using the PokeAPI as the example, and the resolvers live in src/resolvers.ts with the schema in src/schema.graphql.

There is a running instance to look at, at graphql-on-workers.signalnerve.com/___graphql, which is worth doing before reading any code, because a GraphQL API's usefulness is mostly in its interface.

The build is Hono, described as a simple and powerful web framework for Cloudflare Workers, and the server layer comes from the @as-integrations/cloudflare-workers package, which the credits say this project is heavily based on. The README says as much directly, and it is worth crediting rather than treating this as a from scratch Apollo implementation.

Cloning, installing and running locally with wrangler

The setup is two commands, and the third is a script that already exists:

sh
$ git clone https://github.com/cloudflare/workers-graphql-server
$ npm install

You can begin running the project locally by running npm run dev, which the package manifest confirms is a script pointing at wrangler dev. The other scripts are worth reading because they define the whole workflow: deploy runs wrangler deploy, start is also wrangler dev, cf-typegen runs wrangler types to regenerate the worker-configuration.d.ts file, and codegen runs graphql-codegen with the config in codegen.ts.

That last one matters more than it looks. If you change the GraphQL schema at src/schema.graphql, you need to run npm run codegen to update the generated types in src/generated/graphql.ts, and the README explains the reason: it ensures that you can correctly import and type your resolvers.

So the loop is schema first, then codegen, then resolver. A resolver that does not match the generated types is a type error rather than a runtime surprise, which is the entire point of generating them.

The dependencies are Apollo Server at 4.11.0, graphql at 16.9.0, hono at 4.6.5 and the workers integration package at 1.0.2, with wrangler 3.60.3 and the graphql-codegen toolchain in dev dependencies.

The options object is where the behaviour lives

The configuration section describes an optional graphQLOptions object in src/index.js, and the default shape is short:

js
const graphQLOptions = {
  baseEndpoint: '/',
  enableSandbox: true,
  forwardUnmatchedRequestsToOrigin: false,
  cors: true,
  kvCache: false,
}

Each key has a stated default and a reason. The baseEndpoint is the path your POST requests go to. The Apollo Sandbox is enabled by default, which lets you test the GraphQL in a web GUI without writing any client code, and that is a development convenience you probably want off in production.

forwardUnmatchedRequestsToOrigin exists for a specific case: if you run the GraphQL server on a domain already registered with Cloudflare, you may want unmatched requests from inside the Workers script to pass to your origin. On a Workers.dev subdomain the default of false is fine.

The debug flag is described in its own subsection: setting it to true returns script errors in the browser, which is useful while configuring the server and should be disabled on a production server.

The CORS default allows cross-origin requests from any origin. The documentation says you may want to configure it to whitelist specific origins, methods or headers, and the option takes an object based on the hono/cors middleware, with origin, allowHeaders, allowMethods, exposeHeaders, maxAge and credentials. That default is the one to look at first in a review.

KV caching lives inside the resolver, with a required binding name

Caching is opt-in and works through Workers KV. You create a KV namespace, configure it in wrangler.toml, and the binding name is required to be KV_CACHE:

toml
# wrangler.toml

[[kv-namespaces]]
binding = "KV_CACHE"
id = "$myId"

The name is not free choice, which the README notes as currently required. With the namespace in place you turn the feature on by setting the kvCache config value in graphQLOptions to true.

The cache object is then available in the resolver context, and the example shows the shape of a cached resolver:

ts
pokemon: async (_parent, { id }, { cache }) => {
  if (cache) {
    const pokemon = await cache.get(id)
    if (pokemon) {
      return pokemon
    }
  }

and the write side, with an optional TTL:

ts
  if (cache) await cache.set(id, pokemonData, { ttl: 60 })
  return pokemonData

The pattern is the one you would expect from a KV backed cache: read, fall through to the origin call, then write with an expiry. The interesting part is that the cache is a resolver context value rather than something the framework manages, so a resolver that ignores it simply does not cache, and there is no invalidation story beyond the TTL.

Service bindings let resolvers call other Workers

Beyond fetching external APIs, the README notes you can use Service Bindings to connect to other Workers services and use them inside your resolvers.

That is the piece that makes a Worker hosted GraphQL API more than a proxy. A resolver can call a sibling Worker over a service binding instead of going out to the public internet and back, which keeps the call inside Cloudflare's network and avoids exposing an internal service publicly.

It also composes with the D1 story in the project description. If you are deploying databases to Cloudflare directly, a resolver can query D1 and the whole path stays on the platform, which is the arrangement the template is really aimed at.

The limitation follows from the runtime. A Worker has CPU time limits and no long lived process, so a resolver that runs a heavy database query or a long computation is a different problem from the same query behind a normal Node server. The template is at its best when the graph is shallow and the data is close, which is also when edge execution actually pays for itself.

Version 2 moved to a Wrangler 3 and Apollo Server 4 stack

The release history is short. Version 2.0.0 was tagged on 2024-10-25 and 2.0.1 on 2024-11-04, and before that v1.2.0 dates from 2021-10-06. So the project jumped from a 1.x line to a 2.x line in late 2024 and has not published a release since.

The repository is not archived, and the last push was on 2026-04-23, which is several months before the present date. The manifest version reads 2.0.0 while the newest tag is 2.0.1, the usual drift between a manifest that is bumped at release time and a tag applied afterwards.

The dependency pins tell you what era the template belongs to. Apollo Server is at ^4.11.0,, graphql at ^16.9.0, hono at ^4.6.5 and wrangler at ^3.60.3. A team on current wrangler will find the toolchain behind what Cloudflare itself ships.

The README states the project is licensed under the MIT License, and points to the LICENSE file in the repository. The licence field on the repository itself is not filled in, so the README and the file are the places to check rather than the repository metadata.

Editorial conclusion

workers-graphql-server suits a team that wants a read-heavy GraphQL API served close to its users without running a Node server, since the Worker runtime handles the request path and the KV cache sits right inside the resolvers. It is the wrong starting point if you need long running queries, mutations with heavy database work, or a GraphQL API that must live inside an existing Node deployment. Before adopting it, read the cache binding requirement, since the binding name KV_CACHE is currently mandatory, and confirm that the Apollo Server version in the manifest matches what your other services use.

Frequently asked questions

How do I run workers-graphql-server locally?

Clone the repository and run npm install, then npm run dev, which the package manifest defines as wrangler dev. You will also need to configure wrangler.toml before deploying, and run npm run codegen after any change to src/schema.graphql.

How do I enable caching in workers-graphql-server?

Create a Workers KV namespace, configure it in wrangler.toml with the binding name KV_CACHE, which the README says is currently required, and set the kvCache value in graphQLOptions to true. The cache object is then available in resolvers through the resolver context, with get and set and an optional TTL.

What is workers-graphql-server built on?

It is an Apollo GraphQL server built with Cloudflare Workers, using Hono as the web framework and the @as-integrations/cloudflare-workers package, which the credits say the project is heavily based on. The manifest pins Apollo Server at 4.11.0, graphql at 16.9.0, hono at 4.6.5 and wrangler at 3.60.3.

Official sources

  1. cloudflare/workers-graphql-server on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
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/cloudflare-workers-graphql-server.svg)](https://hysenlabs.com/projects/cloudflare-workers-graphql-server)

Was this useful?