Best GraphQL API Boilerplates 2026
TL;DR
GraphQL Yoga + Pothos is the best code-first GraphQL starter for TypeScript projects in 2026 — fully typed schema, no codegen, and deploys to any runtime. Hasura remains the fastest path from an existing PostgreSQL database to a production GraphQL API without writing resolver code. For teams already invested in a framework, NestJS GraphQL and Mercurius (Fastify) provide tight integration with their respective ecosystems, while Strawberry is the clear choice for Python shops.
Why GraphQL Boilerplates in 2026?
GraphQL's value proposition has not changed since its introduction: a typed query language where the client specifies exactly what data it needs. What has changed is the tooling. The schema-first vs. code-first debate is largely settled — code-first won for TypeScript projects (Pothos, Nexus, TypeGraphQL), while schema-first still has proponents in polyglot organizations where the .graphql files serve as contracts between teams.
The boilerplate landscape reflects this maturity. Early GraphQL starters were minimal — an Express server with apollo-server-express and a single resolver file. Current starters include subscription support, DataLoader patterns for N+1 prevention, authentication middleware, rate limiting per query complexity, and deployment configurations for serverless and edge runtimes. The gap between a "hello world" GraphQL server and a production-ready one is substantial, and good boilerplates close it.
One honest caveat: GraphQL is not always the right choice. If your API has a small surface area, serves a single client, or does not require the client to select fields dynamically, REST or tRPC will be simpler with less overhead. GraphQL shines when multiple clients (web, mobile, third-party) consume the same API with different data requirements, or when the data graph is deeply nested and relational.
Quick Comparison
| Starter | Price | Language | GraphQL Library | Auth | Best For |
|---|---|---|---|---|---|
| GraphQL Yoga + Pothos | Free | TypeScript | Yoga + Pothos | Plugin-based | Code-first TypeScript APIs |
| Apollo Server Template | Free | TypeScript | Apollo Server 4 | Custom / 3rd-party | Schema-first teams, Apollo ecosystem |
| Hasura | Free tier + paid | Any (Postgres) | Hasura Engine | JWT / Webhook | Instant API from existing database |
| Mercurius (Fastify) | Free | TypeScript | Mercurius | Fastify auth plugins | Fastify-based backends |
| NestJS GraphQL | Free | TypeScript | Apollo or Mercurius | Guards + Passport | Enterprise Node.js teams |
| Strawberry | Free | Python | Strawberry | Custom middleware | Python-first teams |
The Starters
GraphQL Yoga + Pothos — Best Code-First TypeScript Starter
Price: Free (MIT) | Maintained by: The Guild
GraphQL Yoga is The Guild's HTTP server for GraphQL, and Pothos (formerly GiraphQL) is the code-first schema builder that pairs with it. Together they form the most complete TypeScript-native GraphQL stack in 2026. The combination replaced Nexus as the community default after Nexus development stalled in 2023.
What makes this pairing work: Pothos defines your schema entirely in TypeScript. Types, resolvers, input objects, and interfaces are all TypeScript code — no .graphql files, no codegen step, no runtime schema parsing. The schema is the code. TypeScript catches type mismatches between your resolvers and your schema at compile time rather than at request time. If your resolver returns a string where the schema expects an Int, tsc tells you before you deploy.
The Yoga server handles the HTTP layer — parsing requests, managing subscriptions via Server-Sent Events (SSE) or WebSockets, batching, file uploads, and response streaming. It runs on Node.js, Bun, Deno, Cloudflare Workers, and AWS Lambda without adapter changes. The plugin system handles concerns like authentication, caching, rate limiting, and APM integration (OpenTelemetry, Sentry).
A typical Yoga + Pothos starter includes:
// schema/builder.ts — Pothos schema builder
import SchemaBuilder from '@pothos/core';
import PrismaPlugin from '@pothos/plugin-prisma';
import RelayPlugin from '@pothos/plugin-relay';
import ScopeAuthPlugin from '@pothos/plugin-scope-auth';
import type PrismaTypes from '../generated/prisma-pothos-types';
import { prisma } from '../lib/prisma';
export const builder = new SchemaBuilder<{
PrismaTypes: PrismaTypes;
Context: { userId: string | null };
AuthScopes: { authenticated: boolean; admin: boolean };
}>({
plugins: [PrismaPlugin, RelayPlugin, ScopeAuthPlugin],
prisma: { client: prisma },
authScopes: async (context) => ({
authenticated: !!context.userId,
admin: context.userId ? await isAdmin(context.userId) : false,
}),
});
// schema/user.ts — type-safe resolver
builder.prismaObject('User', {
fields: (t) => ({
id: t.exposeID('id'),
email: t.exposeString('email'),
name: t.exposeString('name', { nullable: true }),
posts: t.relation('posts', {
query: { orderBy: { createdAt: 'desc' } },
}),
}),
});
builder.queryField('me', (t) =>
t.prismaField({
type: 'User',
nullable: true,
authScopes: { authenticated: true },
resolve: (query, _root, _args, ctx) =>
prisma.user.findUnique({ ...query, where: { id: ctx.userId! } }),
}),
);
The Pothos + Prisma plugin automatically generates efficient SQL — including only the fields and relations the client actually requested. This eliminates the classic GraphQL N+1 problem without manual DataLoader setup for Prisma relations.
Choose if: You are building a new TypeScript GraphQL API and want full type safety from database to client with no codegen step.
Apollo Server Templates — Best for Schema-First Teams
Price: Free (MIT) | Maintained by: Apollo (acquired by IBM)
Apollo Server 4 is the most widely deployed GraphQL server in production. The template ecosystem includes official starters for Express, Fastify, AWS Lambda, Azure Functions, and standalone HTTP. Apollo's schema-first approach — you write .graphql schema files and implement resolvers separately — is the opposite of Pothos's code-first model.
The Apollo ecosystem includes Apollo Studio for schema registry and change management, Apollo Router for federated GraphQL (combining multiple GraphQL services into a single endpoint), and Apollo Client for frontend state management. If your organization uses Apollo Federation to compose a supergraph from multiple team-owned subgraphs, Apollo Server is the natural choice for each subgraph.
A standard Apollo Server 4 starter scaffolds:
// server.ts — Apollo Server 4 with Express
import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import express from 'express';
import cors from 'cors';
const typeDefs = `#graphql
type User {
id: ID!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
author: User!
}
type Query {
me: User
posts(limit: Int, offset: Int): [Post!]!
}
`;
const resolvers = {
Query: {
me: (_: unknown, __: unknown, ctx: Context) =>
ctx.dataSources.users.getById(ctx.userId),
posts: (_: unknown, args: { limit?: number; offset?: number }, ctx: Context) =>
ctx.dataSources.posts.list(args.limit ?? 20, args.offset ?? 0),
},
User: {
posts: (user: User, _: unknown, ctx: Context) =>
ctx.dataSources.posts.getByAuthor(user.id),
},
};
const server = new ApolloServer({ typeDefs, resolvers });
await server.start();
const app = express();
app.use('/graphql', cors(), express.json(), expressMiddleware(server, {
context: async ({ req }) => ({
userId: await getUserIdFromToken(req.headers.authorization),
dataSources: { users: new UserAPI(), posts: new PostAPI() },
}),
}));
The main difference from Yoga + Pothos: your schema is defined in SDL (Schema Definition Language) strings or .graphql files, not TypeScript code. This means the schema serves as a language-agnostic contract — useful when backend and frontend teams work in different languages or when you want non-developers (product managers, API consumers) to read the schema directly. The tradeoff is that resolvers are not type-checked against the schema at compile time without additional codegen tools like GraphQL Code Generator.
Apollo Server 4 dropped built-in subscription support. If you need real-time subscriptions, you'll add graphql-ws separately or use a different server for the subscription endpoint.
Choose if: Your team prefers schema-first development, you use Apollo Federation, or you need the Apollo Studio tooling for schema governance.
Hasura — Instant GraphQL on Postgres
Price: Free (Docker self-hosted), Cloud from $0/mo free tier, Pro from $99/mo | Maintained by: Hasura Inc.
Hasura takes a fundamentally different approach: point it at a PostgreSQL database and it generates a complete GraphQL API automatically — queries, mutations, subscriptions, filtering, pagination, ordering, and aggregation. No resolvers to write. No schema to maintain manually. The GraphQL schema is derived from your database schema.
This is not a toy. Hasura generates efficient SQL from GraphQL queries, supports real-time subscriptions (live queries that push updates when underlying data changes), handles authorization through row-level security rules defined in a metadata file, and integrates with remote schemas and REST endpoints for data that does not live in your database. Production deployments serve thousands of requests per second.
# hasura/metadata/databases/default/tables/public_posts.yaml
table:
schema: public
name: posts
array_relationships:
- name: comments
using:
foreign_key_constraint_on:
column: post_id
table:
schema: public
name: comments
select_permissions:
- role: user
permission:
columns: [id, title, content, created_at, author_id]
filter:
_or:
- is_published: { _eq: true }
- author_id: { _eq: X-Hasura-User-Id }
The permission system is where Hasura earns its production credentials. You define row-level and column-level permissions per role, and Hasura compiles these into SQL WHERE clauses that run at the database level. A user role can only see published posts or their own drafts — enforced in every query without any application code.
Hasura Cloud adds monitoring, caching, rate limiting, and a managed infrastructure layer. The self-hosted Docker image is free and fully functional.
Choose if: You have an existing PostgreSQL database and want a GraphQL API without writing backend code, or you need real-time subscriptions with minimal setup.
Mercurius — Best for Fastify Teams
Price: Free (MIT) | Maintained by: Fastify team (Matteo Collina)
Mercurius is the official GraphQL adapter for Fastify. If you already use Fastify — or are evaluating it for a new project after reading our Hono backend boilerplates guide — Mercurius integrates GraphQL as a first-class Fastify plugin rather than a bolt-on middleware.
The performance story matters here. Fastify is already the fastest mainstream Node.js HTTP framework, and Mercurius adds GraphQL processing with minimal overhead. Mercurius uses graphql-jit to JIT-compile GraphQL operations into optimized JavaScript functions on first execution. Subsequent executions of the same query skip the parsing and validation steps entirely. For APIs with a known set of operations (persisted queries), this means GraphQL processing overhead approaches zero after warmup.
import Fastify from 'fastify';
import mercurius from 'mercurius';
const app = Fastify({ logger: true });
const schema = `
type Query {
projects(status: String): [Project!]!
}
type Project {
id: ID!
name: String!
stars: Int!
language: String!
}
`;
const resolvers = {
Query: {
projects: async (_: unknown, args: { status?: string }, ctx: MercuriusContext) => {
return ctx.app.db.project.findMany({
where: args.status ? { status: args.status } : undefined,
});
},
},
};
app.register(mercurius, {
schema,
resolvers,
graphiql: true, // GraphiQL IDE at /graphiql
subscription: true, // WebSocket subscriptions
jit: 1, // JIT-compile after 1st execution
});
await app.listen({ port: 3000 });
Mercurius supports subscriptions out of the box (unlike Apollo Server 4), federated schemas via @mercuriusjs/federation, and gateway composition via @mercuriusjs/gateway. The Fastify plugin ecosystem — authentication (@fastify/auth, @fastify/jwt), rate limiting (@fastify/rate-limit), caching (@fastify/caching) — works seamlessly alongside Mercurius.
Choose if: You are building on Fastify and want GraphQL as a native plugin rather than a separate middleware layer, or you need JIT-compiled query performance.
NestJS GraphQL Starter — Best for Enterprise Node.js
Price: Free (MIT) | Maintained by: NestJS team (Kamil Mysliwiec)
NestJS is the most popular enterprise Node.js framework, and its GraphQL module is the most structured way to build a GraphQL API in TypeScript. NestJS GraphQL supports both code-first (using TypeScript decorators to generate the schema) and schema-first (using .graphql files with generated TypeScript types) approaches.
The code-first approach in NestJS uses decorators — @ObjectType(), @Field(), @Query(), @Mutation() — to define the schema directly on TypeScript classes. This is similar in spirit to Pothos but uses the decorator pattern familiar to Angular and NestJS developers rather than a builder API:
// user.model.ts
@ObjectType()
export class User {
@Field(() => ID)
id: string;
@Field()
email: string;
@Field(() => [Post])
posts: Post[];
}
// user.resolver.ts
@Resolver(() => User)
export class UserResolver {
constructor(private userService: UserService) {}
@Query(() => User, { nullable: true })
@UseGuards(GqlAuthGuard)
async me(@CurrentUser() user: JwtPayload): Promise<User | null> {
return this.userService.findById(user.sub);
}
@ResolveField(() => [Post])
async posts(@Parent() user: User): Promise<Post[]> {
return this.userService.getPostsByUser(user.id);
}
}
NestJS's dependency injection container, guards (authentication), interceptors (logging, caching), and pipes (validation) all work with GraphQL resolvers identically to how they work with REST controllers. If your organization already uses NestJS for REST APIs, adding a GraphQL layer requires learning the GraphQL-specific decorators but not a new architectural pattern.
The NestJS GraphQL starter includes Prisma or TypeORM integration, JWT authentication guards, role-based authorization, health checks, and OpenTelemetry instrumentation. It can use Apollo Server or Mercurius as the underlying GraphQL engine.
Choose if: Your team uses NestJS, you want dependency injection and enterprise patterns (CQRS, event sourcing) alongside GraphQL, or you need both REST and GraphQL endpoints in the same application.
Strawberry — Best for Python Teams
Price: Free (MIT) | Maintained by: Strawberry team (Patrick Arminio)
Strawberry is a Python GraphQL library that uses Python type hints and dataclasses to define the schema — no string-based SDL, no separate schema files. It is to Python what Pothos is to TypeScript: a code-first approach where the language's type system is the schema definition.
import strawberry
from strawberry.fastapi import GraphQLRouter
from fastapi import FastAPI
@strawberry.type
class User:
id: strawberry.ID
email: str
name: str | None
@strawberry.type
class Query:
@strawberry.field
async def me(self, info: strawberry.Info) -> User | None:
user_id = info.context["user_id"]
if not user_id:
return None
return await get_user(user_id)
@strawberry.field
async def users(
self,
limit: int = 20,
offset: int = 0,
) -> list[User]:
return await list_users(limit=limit, offset=offset)
schema = strawberry.Schema(query=Query)
app = FastAPI()
graphql_router = GraphQLRouter(schema)
app.include_router(graphql_router, prefix="/graphql")
Strawberry integrates with FastAPI, Django, Flask, and ASGI servers. The FastAPI integration is the most common production pattern — FastAPI handles HTTP, authentication, and middleware while Strawberry handles GraphQL schema and resolution. For teams already using FastAPI for REST endpoints (see our FastAPI boilerplates guide), adding a GraphQL endpoint via Strawberry is a natural extension rather than a separate service.
Strawberry supports subscriptions (via WebSockets with ASGI), file uploads, DataLoader for N+1 prevention, and federation for composing multiple Strawberry services into a supergraph. The type hint integration means mypy and pyright catch schema errors at static analysis time.
Choose if: Your backend is Python, you want GraphQL alongside existing FastAPI or Django services, or your team prefers Python's type hint syntax over TypeScript.
When to Use Which
The choice between these starters depends on three factors: your existing stack, your schema philosophy, and your deployment target.
Starting from scratch with TypeScript? GraphQL Yoga + Pothos. The type safety is unmatched, the deployment flexibility (Node.js, Bun, Cloudflare Workers, Lambda) is the broadest, and the Prisma integration handles database access with minimal boilerplate. This is the default recommendation for new projects.
Have an existing PostgreSQL database? Hasura. If the data is already in Postgres and you need an API quickly — internal tools, admin dashboards, mobile apps for existing web data — Hasura generates a production-quality API in minutes rather than days. Add custom business logic via Hasura Actions (webhooks to your own endpoints) when you outgrow the auto-generated CRUD.
Already on Fastify? Mercurius. Do not add Apollo Server as a middleware on top of Fastify — use the native plugin. You get JIT compilation, built-in subscriptions, and access to the full Fastify plugin ecosystem without adapter friction.
Enterprise NestJS shop? NestJS GraphQL. The dependency injection, guards, and interceptors you already know work identically with GraphQL resolvers. Retraining cost is minimal.
Python backend? Strawberry + FastAPI. The type hint integration is clean, the FastAPI router plugin means GraphQL is one more route on your existing server, and mypy catches schema errors in CI.
Schema-first with federation? Apollo Server + Apollo Router. If your organization has multiple teams owning separate subgraphs that compose into a federated supergraph, Apollo's tooling (Studio, Router, schema checks) is the most mature option for schema governance at scale.
GraphQL Performance Patterns
Regardless of which starter you choose, three performance patterns are essential for production GraphQL APIs:
DataLoader for N+1 prevention. Every GraphQL server that resolves nested relations will hit the N+1 query problem without DataLoader. A query for 20 posts with their authors triggers 1 query for posts + 20 individual queries for each author. DataLoader batches those 20 author lookups into a single WHERE id IN (...) query. Pothos handles this automatically for Prisma relations. Apollo Server and Mercurius require explicit DataLoader setup.
Query complexity analysis. GraphQL's flexibility is also its risk — a client can request deeply nested data that generates expensive database queries. Production APIs should limit query depth (typically 7-10 levels) and assign complexity scores to fields. Libraries like graphql-query-complexity calculate the total cost of a query before execution and reject queries that exceed a threshold.
Persisted queries. For production APIs where the set of operations is known (your own frontend), persisted queries replace the full query string with a hash. The client sends { "id": "abc123" } instead of the entire query text. This reduces request payload size, prevents arbitrary query injection, and enables the server to pre-compile and cache execution plans.
Related Resources
For backend API starter kits in other paradigms, see our guide to Hono backend boilerplates (REST and RPC patterns for edge deployment) and FastAPI boilerplates (Python REST APIs). If you want to deepen your Node.js fundamentals before building a GraphQL server, CourseFacts maintains a curated list of best Node.js courses in 2026. Browse all backend and API starter kits at StarterPick.
Methodology
This article reflects evaluation of GraphQL boilerplates and frameworks available in 2026, including API surface review, documentation quality, TypeScript type safety, deployment flexibility, and community adoption. Performance claims reference published benchmarks and are presented as directional guidance — real-world performance depends on query patterns, database design, and infrastructure. Pricing reflects publicly available tiers at the time of writing.
Check out this boilerplate
View GraphQL Yoga Starteron StarterPick →