# Apollo Server 5: the @apollo/server package, Express setup and what changed since version 4

> Apollo Server is the MIT-licensed JavaScript GraphQL server behind the @apollo/server package, usable standalone or as Express middleware. The README covers the happy path well and leaves HTTP-level tuning, rollback and migration detail to the docs site.

**apollographql/apollo-server** — 🌍  Spec-compliant and production ready JavaScript GraphQL server that lets you develop in a schema-first way. Built for Express, Connect, Hapi, Koa, and more.

- Repository: https://github.com/apollographql/apollo-server
- Website: https://www.apollographql.com/docs/apollo-server/
- Stars: 13,954 · Forks: 2,004
- Language: TypeScript
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/apollographql-apollo-server

## Who @apollo/server is for, and the problem it removes

Writing a GraphQL server by hand means implementing the specification yourself: parsing and validating operations, resolving fields, shaping the response envelope, and handling errors in the format clients expect. Apollo Server takes that layer. The README describes it as an open-source, spec-compliant GraphQL server compatible with any GraphQL client, including Apollo Client, and says it is a way to build a self-documenting GraphQL API that can use data from any source. The self-documenting part is inherent to GraphQL rather than an Apollo feature: the schema is the contract, and tooling can read it.

The audience is Node developers who already have data behind an API, a database or several services, and want one typed entry point in front of it. The README lists three deployment shapes: a stand-alone GraphQL server, the GraphQL server for a subgraph in a federated supergraph, and the gateway for a federated supergraph. The first is the common case. The other two matter if you are splitting a graph across teams, and they are a different commitment, because federation adds its own packages and vocabulary.

One structural detail is easy to miss. The README states that @apollo/server is new since Apollo Server 4, and that previous major versions used package names starting with apollo-server, such as apollo-server, apollo-server-express and apollo-server-core. If you are following a tutorial that imports from apollo-server-express, you are reading version 3 material. The import paths differ, so the code will not run against the current package.

## How the server is put together: typeDefs, resolvers, plugins

The mechanism is small enough to hold in your head. You hand the ApolloServer constructor two things: typeDefs, a GraphQL schema written as a string, and resolvers, a map of functions that return data for the schema. The constructor validates the schema at startup, which is why a malformed schema fails at boot rather than on the first request.

In the standalone example the README gives, the server is created and then startStandaloneServer is awaited, returning an object with a url property that the example logs. The README states that this standalone server handles CORS and body parsing out of the box, and that it allows the same configuration of GraphQL logic as the Express integration but does not provide the ability to make fine-grained tweaks to the HTTP-specific behaviour of your server. That sentence is the whole trade-off between the two paths. The standalone server is less code and less control.

The Express path changes the shape of the program. You create an Express app and an http.Server around it, pass ApolloServerPluginDrainHttpServer with the http server into the plugins array, await server.start(), then mount expressMiddleware(server) on the app. The drain plugin exists because the HTTP server and the GraphQL server have separate lifecycles; the plugin is how the README wires them together so the HTTP server can be closed cleanly. Plugins are the extension point in this design. Rather than subclassing, you pass an array, and the built-in drain plugin is the first entry most projects add.

## Installing Apollo Server and running a first query

The README gives two install commands. The standalone route needs the server package and the JavaScript implementation of the core GraphQL algorithms:

```bash
npm install @apollo/server graphql
```

Write the server to a file with the .mjs extension. The README notes that this extension lets Node use await at the top level, which is why the example does not wrap anything in an async function.

```js
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';

const typeDefs = `#graphql
  type Query {
    hello: String
  }
`;

const resolvers = {
  Query: {
    hello: () => 'world',
  },
};

const server = new ApolloServer({ typeDefs, resolvers });
const { url } = await startStandaloneServer(server);
console.log(`Server ready at ${url}`);
```

Run it with node server.mjs. Open the printed URL in a browser and you get Apollo Sandbox, a web-based tool for running GraphQL operations. Run query { hello } and the resolver returns world. If you would rather embed the server in an existing Express app, the install line grows:

```bash
npm install @apollo/server @as-integrations/express5 graphql express cors
```

The README also notes that TypeScript users may need type declaration packages as development dependencies to avoid errors such as a missing declaration file for cors, and gives npm install --save-dev @types/cors @types/express for that. The Express example listens on port 4000 and mounts cors(), express.json() and expressMiddleware(server) in that order. Note the integration package name: @as-integrations/express5 targets Express 5, so an Express 4 app needs the matching integration package instead.

## Where Apollo Server 5 is the wrong choice

The standalone server cannot be tuned at the HTTP layer. The README says this plainly: it does not provide the ability to make fine-grained tweaks to the HTTP-specific behaviour of your server. If you need custom status codes, unusual content negotiation, request-level timeouts or a specific middleware order, you are on the Express path or a similar integration, and the standalone convenience is gone.

Integrations are a second boundary. The README states that the @apollo/server package ships with a minimally-configurable standalone web server, and that integrations with other environments are community-maintained. That is a real cost when you pick Hapi, Koa, Fastify or a serverless runtime: the maintenance of the glue sits with whoever publishes the integration, not with the core package. The repository topics list Express, Hapi, Koa and Restify, but the README's own examples only walk through standalone and Express.

The third case is scale of ambition. Apollo Server is one graph. If your problem is composing many independently deployed services into one schema, the README points at federation, which involves a subgraph role or a gateway role and additional packages. Reaching for Apollo Server as a plain server when you actually need a gateway means you will rewrite the entry point later.

Finally, the README is a starting point, not a reference. It says most features are only documented on the docs site. Anything about caching, error formatting, context construction or plugin authoring has to come from there, and this README will not tell you whether a given option still exists in version 5.

## Apollo Server compared with graphql-http and express-graphql

The closest alternative for a Node HTTP GraphQL endpoint is graphql-http, the reference HTTP transport implementation maintained by the GraphQL Foundation. The difference is scope. graphql-http implements the GraphQL over HTTP specification and leaves schema execution to graphql-js; it has no opinion about plugins, no standalone server with CORS and body parsing built in, and no gateway or subgraph mode. Apollo Server wraps the same underlying graphql package, which is why the install command pulls in graphql alongside it, and adds the lifecycle around it: plugins, the drain helper, and the start/stop sequence.

If you want the smallest possible dependency surface and you are comfortable wiring your own HTTP framework, graphql-http is the more literal choice. If you want a server that starts with two arguments and grows through plugins, Apollo Server is the shorter path. The older express-graphql package occupies the same niche as the Express integration here and is the thing most version 3 tutorials were written against, so treat it as historical when you are choosing today.

The comparison is not about correctness. Both are spec-oriented. It is about how much framework you want around the execution engine, and whether you want that framework to be the one Apollo maintains.

## Maintenance, upgrades and the MIT licence

The repository is not archived and the last push was on 2026-09-20, one day before this article's reference point, so the codebase is being changed. The most recent release listed is @apollo/server@5.5.1, published on 2026-05-05, alongside @apollo/server-integration-testsuite@5.5.1 the same day and @apollo/usage-reporting-protobuf@4.1.2 on 2026-05-04. Releases and pushes are not the same thing: the push date tells you the repository is active, the release date tells you when the published artefact last changed.

The upgrade cost is concentrated in major versions, and the README provides the evidence. It states that @apollo/server is new since Apollo Server 4 and that earlier majors used a family of apollo-server-* packages. A version 3 to version 4 move is therefore a package rename and an import rewrite, not a version bump. The monorepo uses changesets for releases, which is visible in the package.json scripts, but that is a maintainer workflow detail rather than something that reduces the cost on your side.

Runtime requirements are stated: the root package.json sets engines to node >=20 and npm >=8.19.2. If you are on an older Node release, the install will not match the supported range. The licence is MIT, declared both in the repository metadata and in the root package.json. MIT is permissive and permits commercial use and modification; the standard obligation is to keep the copyright and licence notice with copies of the software. Whether that obligation attaches to your particular distribution is a question for your own counsel, not for this article.

## Conclusion

Adopt it if you want a schema-first GraphQL endpoint in Node and are willing to treat the docs site, not the README, as the reference. Do not adopt it if you need fine-grained control over HTTP behaviour, because the standalone server does not offer that and the README says so. Before committing, check two things: that your runtime is Node 20 or newer, and that your framework has a maintained integration package, since the README describes non-default integrations as community-maintained. Then read the getting started guide on the docs site rather than working from the README alone.

## FAQ

### What is Apollo Server?

It is an open-source, spec-compliant GraphQL server for TypeScript and JavaScript, published as the @apollo/server package. The README describes it as compatible with any GraphQL client and usable as a standalone server, as a subgraph, or as a gateway for a federated supergraph.

### How do I install Apollo Server?

The README gives npm install @apollo/server graphql for the standalone server. For the Express middleware you also install @as-integrations/express5, express and cors, and TypeScript users may need @types/cors and @types/express as dev dependencies.

### How do I set up Apollo Server?

Write a schema as typeDefs and a resolver map, pass both to the ApolloServer constructor, then either await startStandaloneServer(server) or, for Express, await server.start() and mount expressMiddleware(server) on the app. The README's examples use a .mjs file so top-level await works.

### How do I use Apollo Server with Express?

Install @apollo/server, @as-integrations/express5, graphql, express and cors, then import expressMiddleware from @as-integrations/express5 and pass the server instance to it. The README's example also passes ApolloServerPluginDrainHttpServer with the Node http server so the two shut down together.

### Is Apollo Server free?

The repository is licensed under MIT, which is a permissive open-source licence and permits commercial use. The README does not describe paid tiers or usage restrictions for the @apollo/server package itself.

### What is the difference between Apollo Server and Apollo Client?

Apollo Server runs on the backend and executes GraphQL operations against your schema and resolvers. Apollo Client is a client library, and the README lists it as one of the clients Apollo Server is compatible with rather than as part of the server.

## Sources

- [apollographql/apollo-server on GitHub](https://github.com/apollographql/apollo-server)
- [License: MIT](https://github.com/apollographql/apollo-server/blob/main/LICENSE)
- [Project website](https://www.apollographql.com/docs/apollo-server/)
- [README](https://github.com/apollographql/apollo-server/blob/main/README.md)
- [Releases](https://github.com/apollographql/apollo-server/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/apollographql-apollo-server
