swapi-graphql: a GraphQL schema and server over SWAPI
A GraphQL schema and server wrapping SWAPI.
At a glance
- What is it?
- swapi-graphql is a reference implementation that puts a GraphQL schema in front of the SWAPI demo API, with DataLoader doing the batching and caching, a published schema.graphql contract, and a small Express server for local exploration. It is an excellent teaching artefact and a poor production dependency, and the package scripts describe a Netlify deployment rather than the local server the README describes.
- Who is it for?
- Adopt swapi-graphql if you are learning GraphQL by reading a real schema and real resolvers, if you want a working example of DataLoader batching against a REST backend, or if you need a GraphQL front end for a demo API in a talk. Do not adopt it as a production GraphQL server, since it wraps a demonstration dataset and pins GraphQL 14.5.8.
- 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 166 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 6, 2026, and from our analysis. They are not legal advice.
Star history
- graphql/swapi-graphql1,063 ★ · +0
| Repository | 2026-10-20 | 2026-11-06 |
|---|---|---|
| graphql/swapi-graphql | 1.1k | 1.1k |
0 Stars in the last 17 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
A REST API behind a typed GraphQL schema
The project is described as a GraphQL schema and server wrapping SWAPI, and the README puts it more precisely: a wrapper around SWAPI built using GraphQL, converting it into this schema, which is the schema.graphql file at the root of the repository.
That file is the centre of the project. SWAPI is the public upstream API, and this repository takes that and describes it in GraphQL's type system, with queries, types and fields instead of paths and parameters. A client can then ask for exactly the fields it needs, in one request, instead of making several calls and filtering the results.
The dependencies tell you how the work is done. graphql-js is the JavaScript GraphQL runtime, and express-graphql provides the HTTP access to GraphQL. DataLoader is there for coalescing and caching fetches, which is the part that turns this from a demo into a well behaved server, since a GraphQL query that touches several related objects would otherwise produce several HTTP requests to the same upstream, and the loader batches and deduplicates them.
Two deployment paths are advertised with buttons in the README, one for Heroku and one for now, and the repository carries both an app.json and a netlify.toml, so the same code is expected to run on a classic Node host, on a serverless deployment through aws-serverless-express, and on Netlify.
The homepage is graphql.org/swapi-graphql and a live instance is at that address. The repository is not archived, and the last push was on 2026-05-25. Getting the code onto your machine is the npm install the README documents, which also fetches the data and compiles the source:
npm installThe scripts, and where the README and the manifest disagree
The package manifest is the more reliable document here, and reading it alongside the README turns up a discrepancy worth naming before you try to run anything.
The README's getting started section says to install dependencies with npm install, and the manifest confirms that with a postinstall script that runs npm run download and then npm run build. So a plain install fetches data and compiles the source, and the download step is babel-node scripts/download.js cache/data.json, which fetches the dataset into the cache directory that also exists at the repository root.
Then the README says the SWAPI wrapper is in ./swapi and can be tested with yarn test, and that a local express server is in ./server and can be run with npm start, with GraphiQL opened at http://localhost:8080/ or similar, the actual port printed to the console.
The manifest does not agree with that. The start script is netlify build, and the script for a local development server is watch, which runs netlify dev. The test script is npm run lint && npm run check && npm run test:only, with test:only running jest, lint running eslint over src and handler, and check running flow check. There is also a serve-public script that runs babel-node scripts/serve-public.
The repository root does not list a swapi or a server directory at all. What it does list is src/, handler/, cache/, doc/, public/, scripts/ and schema.graphql, which matches the manifest's structure and not the README's.
So the README describes a layout that the current tree does not have. For someone evaluating the project, the practical instruction is to trust the manifest, start with netlify dev for the development server, and use the scripts that exist rather than the ones the prose names. The test entry point, as the README shows it, is:
yarn testand the local server, again as the README describes it, is:
npm startDataLoader is the part worth studying
If you read this repository for one reason, it should be the resolvers and the loaders.
The DataLoader dependency is described in the README as being for coalescing and caching fetches, and the two words cover the two problems a GraphQL layer over a REST API creates.
Coalescing is about the N plus 1 problem. A GraphQL query is a single request that can ask for a list of films and, for each film, its director. Without batching, the server makes one request upstream per film, so a page of twenty results is twenty round trips. With a loader keyed by id, the server collects the ids it needs during a single resolution pass and issues one request for all of them. Caching is the second half, and it covers the case where the same parent is asked for the same child twice, or where two branches of the query reference the same object.
The DataLoader version is pinned at 1.4.0, and the GraphQL runtime at 14.5.8, which tells you the era of the code. The Babel toolchain is the older 6.x line, with babel-runtime at ^6.26.0, and the build script compiles src into lib/ while ignoring __tests__, public and handler. The Flow type checker is wired into the test script through the check script, and the repository carries a .flowconfig.
The engine requirement in the manifest is node >=20.0.0, with a .nvmrc at the root to pin the version for development. The browserify configuration uses babelify to transform the code and shims react to a global, which is a leftover from the era when this project also shipped a browser front end, which is presumably what the public/ directory and the LICENSE-examples file are for.
The schema file is the contract you can read first
One of the things this project does that a live server does not is publish its schema as a file, and that makes it a good artefact to read before you read any code.
The schema.graphql file at the root is the complete description of the API: the types, the fields, the queries, and the relationships between them. The README calls it the schema the wrapper converts SWAPI into, and there are two scripts dedicated to keeping it honest. print-schema runs babel-node scripts/print-schema.js, which prints the schema, and store-schema runs babel-node scripts/store-schema.js, which stores it. The doc/ directory in the repository tree is where the documentation lives.
That arrangement matters for a specific workflow. A GraphQL client, whether a mobile app or a front end you are building, needs to know the shape of the data before it can generate queries, and a schema file is what you hand to a code generator or to a typed client. With this project, the file is committed, so the contract is reviewable in a pull request and diffable when the schema changes.
It also means you can evaluate the project without running it. Reading the schema tells you what the wrapper decided to expose, and the decisions are visible in one place. A wrapper like this is opinionated by nature, since it chooses which upstream fields to surface and how to name the relationships, and the schema is where those choices are recorded.
The data side is equally explicit. The download script writes cache/data.json, and the cache/ directory is committed to the repository, so the project can run against a captured copy of the API responses rather than depending on the live SWAPI service being up at the moment you start it.
Contribution requires a GraphQL membership agreement
The contributing section is unusual and worth reading before you plan to send a pull request.
This repository is managed by EasyCLA, and project participants must sign the free GraphQL Specification Membership agreement before making a contribution. It only has to be done once, and it can be signed by individual contributors or by their employers, with separate links for both routes. To start the process you open a pull request, and the EasyCLA bot will block the merge if a membership agreement is still needed.
The point of the mechanism is clear. The GraphQL specification is a shared, community governed artefact, and the membership agreement is how the foundation keeps the contributor list and the participants of the specification process in a known set of people. Signing it is a precondition for contributing to this repository.
The cost for a contributor is one signature and a legal entity to sign it with, which is a company rather than an individual if you do not have a personal one. The README points at the detailed information in the graphql-wg repository, gives [email protected] as the contact for issues, and closes with a pointer to GraphQL Foundation membership for organisations that benefit from GraphQL and want to support it financially.
For an adopting team, this matters in a different way. If you fork this repository and want to develop it as your own service rather than contribute upstream, the EasyCLA gate does not apply, but the fact that the project sits inside a governance structure with a foundation behind it is part of the context you inherit.
A wrapper of a demo API is not a production backend
The limits of this project are structural, and it is better to say so than to discover them in production.
The first is the upstream. SWAPI is a demonstration API, a stable and well known one, but a demonstration. A wrapper whose data source is a public demo dataset is a teaching example and a component for a tutorial, a talk, a workshop or a test fixture. It is not the foundation of a service that has to answer questions about real data, and the schema will always describe the demo API's shape rather than your domain's.
The second is the age of the stack. GraphQL is pinned at 14.5.8, DataLoader at 1.4.0, Babel at the 6.x line, and the browserify configuration still shims react to a global. These are versions from a period before the current GraphQL server implementations, and while the engine requirement of node 20 or newer keeps the runtime modern, the library versions do not follow it. Starting a new service on this code means upgrading the GraphQL runtime and the toolchain first, and that upgrade is work the project will not do for you.
The third is the deployment story. The manifest's start script is netlify build and the development script is netlify dev, so the project is currently arranged around a specific hosting platform's build pipeline, and the app.json and Heroku button point at a different one. A serverless deployment through aws-serverless-express is described in the dependency list, but the deployment story in the repository is a set of examples rather than a documented platform matrix.
What the project is genuinely good for is the opposite. It is a small, complete, readable GraphQL server with a committed schema, real resolvers, batching, tests, linting and type checking, which makes it a good thing to read when you are learning how a GraphQL layer is supposed to be put together over an existing REST API.
Editorial conclusion
Adopt swapi-graphql if you are learning GraphQL by reading a real schema and real resolvers, if you want a working example of DataLoader batching against a REST backend, or if you need a GraphQL front end for a demo API in a talk. Do not adopt it as a production GraphQL server, since it wraps a demonstration dataset and pins GraphQL 14.5.8. Verify first which script actually starts the local server in your checkout, since the README and the package manifest disagree, that the download step in postinstall can reach the API, and that the licence you need is the BSD 3-Clause named in package.json rather than the MIT recorded in the repository metadata.
Frequently asked questions
How do I run swapi-graphql locally?
Run npm install, which triggers a postinstall that downloads the data with scripts/download.js and builds the source. The manifest's start script is netlify build and the development script is watch, which runs netlify dev, so the README's instruction to run npm start for a local express server does not match the current package scripts.
How does swapi-graphql avoid the N plus 1 problem?
It depends on DataLoader, which the README lists for coalescing and caching fetches, with the package pinned at version 1.4.0. The loader collects the ids needed during a single resolution pass so one upstream request can serve many nodes of the query.
Where is the GraphQL schema defined?
In the schema.graphql file at the root of the repository, which the README calls the schema the wrapper converts SWAPI into. The manifest also provides print-schema and store-schema scripts for working with it, and a doc/ directory for the documentation.
Do I need to sign anything to contribute to swapi-graphql?
Yes. The repository is managed by EasyCLA and participants must sign the free GraphQL Specification Membership agreement before contributing, once, either as an individual contributor or through an employer. Opening a pull request starts the process, and the EasyCLA bot blocks the merge until it is done.
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-swapi-graphql)Star history chart for your README
[](https://hysenlabs.com/projects/graphql-swapi-graphql)Was this useful?