Apollo Server has too many opinions. Express-graphql is abandoned. GraphQL Yoga is the sweet spot — batteries included but not bloated.
What is GraphQL Yoga?
GraphQL Yoga is a full-featured GraphQL server by The Guild (creators of GraphQL Codegen, Envelop, and GraphQL Mesh). It works everywhere — Node.js, Deno, Bun, Cloudflare Workers, AWS Lambda — with built-in subscriptions, file uploads, and error handling.
Why GraphQL Yoga
1. Minimal Setup
import { createServer } from 'node:http';
import { createSchema, createYoga } from 'graphql-yoga';
const yoga = createYoga({
schema: createSchema({
typeDefs: /* GraphQL */ `
type Query {
hello(name: String): String!
users: [User!]!
}
type User {
id: ID!
name: String!
email: String!
}
`,
resolvers: {
Query: {
hello: (_, { name }) => `Hello ${name || 'World'}!`,
users: () => db.users.findMany(),
},
},
}),
});
const server = createServer(yoga);
server.listen(4000, () => console.log('Server is running on http://localhost:4000/graphql'));
2. Deploy Anywhere
// Next.js App Router
import { createYoga } from 'graphql-yoga';
const yoga = createYoga({ schema, graphqlEndpoint: '/api/graphql' });
export { yoga as GET, yoga as POST };
// Cloudflare Workers
export default { fetch: yoga };
// AWS Lambda
export const handler = yoga;
// Deno
Deno.serve(yoga);
// Bun
Bun.serve({ fetch: yoga });
3. Built-in Subscriptions (WebSocket + SSE)
const schema = createSchema({
typeDefs: `
type Subscription {
countdown(from: Int!): Int!
newMessage: Message!
}
`,
resolvers: {
Subscription: {
countdown: {
async *subscribe(_, { from }) {
for (let i = from; i >= 0; i--) {
await new Promise(r => setTimeout(r, 1000));
yield { countdown: i };
}
},
},
},
},
});
4. File Uploads
const schema = createSchema({
typeDefs: `
scalar File
type Mutation {
uploadFile(file: File!): String!
}
`,
resolvers: {
Mutation: {
uploadFile: async (_, { file }) => {
const buffer = await file.arrayBuffer();
await fs.writeFile(`uploads/${file.name}`, Buffer.from(buffer));
return `Uploaded ${file.name} (${file.size} bytes)`;
},
},
},
});
5. Envelop Plugin System
import { useDisableIntrospection } from '@envelop/disable-introspection';
import { useDepthLimit } from '@envelop/depth-limit';
import { useResponseCache } from '@graphql-yoga/plugin-response-cache';
const yoga = createYoga({
schema,
plugins: [
useDisableIntrospection(), // Security
useDepthLimit({ maxDepth: 10 }), // Prevent deep queries
useResponseCache({ ttl: 5000 }), // Cache responses
],
});
GraphQL Yoga vs Apollo Server vs Mercurius
| Yoga | Apollo Server | Mercurius | |
|---|---|---|---|
| Size | Lightweight | Heavy | Lightweight |
| Subscriptions | Built-in (SSE+WS) | Separate package | Built-in |
| File uploads | Built-in | Via apollo-upload | Plugin |
| Deploy targets | Any runtime | Node.js focused | Fastify only |
| Plugin system | Envelop | Apollo plugins | Fastify plugins |
| Maintained by | The Guild | Apollo | Fastify team |
Getting Started
npm install graphql-yoga graphql
The Bottom Line
GraphQL Yoga is GraphQL done right. Lightweight, runs anywhere, with batteries included. If you're starting a new GraphQL API, this is the best starting point.
Need data tools? I build scraping solutions. Check my Apify actors or email spinov001@gmail.com.
Top comments (0)