graphql-yoga vs apollo-server vs type-graphql
GraphQL Server Frameworks for Node.js
graphql-yogaapollo-servertype-graphqlSimilar Packages:

GraphQL Server Frameworks for Node.js

apollo-server, graphql-yoga, and type-graphql are tools that help developers build GraphQL APIs in Node.js, but they serve different roles in the stack. apollo-server is a standalone GraphQL server implementation with extensive plugin support and ecosystem integration. graphql-yoga is a modern, batteries-included GraphQL server that prioritizes developer experience and spec compliance, built on top of Envelop and GraphQL-JS. type-graphql is not a server itself but a library that generates GraphQL schema definitions from TypeScript classes using decorators, often used alongside a GraphQL server like Apollo or Yoga to reduce boilerplate.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
graphql-yoga932,3118,487293 kB1302 months agoMIT
apollo-server013,94826.6 kB802 years agoMIT
type-graphql08,092351 kB11320 days agoMIT

Building GraphQL APIs in Node.js: Apollo Server vs GraphQL Yoga vs TypeGraphQL

When building a GraphQL API in Node.js, you’ll quickly realize these three packages solve different parts of the problem. apollo-server and graphql-yoga are full GraphQL servers — they handle HTTP requests, execute queries, and return responses. type-graphql is a schema-generation tool that works with a server. Understanding their roles is key to making the right architectural choice.

🧱 Core Responsibilities: What Each Package Actually Does

apollo-server is a production-ready GraphQL server that implements the GraphQL specification and provides a robust HTTP layer. It supports middleware, plugins, subscriptions, and integrates tightly with Apollo’s ecosystem.

// apollo-server: Standalone server
import { ApolloServer } from 'apollo-server';
import { typeDefs, resolvers } from './schema';

const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => console.log(`Running at ${url}`));

graphql-yoga is also a complete GraphQL server, but it’s designed to be simpler and more opinionated. It includes built-in support for GraphQL over HTTP (GET/POST), file uploads, persisted operations, and error masking — all with minimal config.

// graphql-yoga: Zero-config server
import { createYoga } from 'graphql-yoga';
import { createServer } from 'http';
import { schema } from './schema';

const yoga = createYoga({ schema });
const server = createServer(yoga);
server.listen(4000, () => console.log('Running on http://localhost:4000/graphql'));

type-graphql doesn’t run a server. Instead, it lets you define your GraphQL schema using TypeScript classes and decorators. You still need a server (like Apollo or Yoga) to actually serve the API.

// type-graphql: Schema definition only
import { ObjectType, Field, Resolver, Query } from 'type-graphql';

@ObjectType()
class User {
  @Field()
  id: string;

  @Field()
  name: string;
}

@Resolver()
class UserResolver {
  @Query(() => User)
  user() {
    return { id: '1', name: 'Alice' };
  }
}

// Later, pass the generated schema to a server:
// const schema = await buildSchema({ resolvers: [UserResolver] });

💡 Key insight: type-graphql is complementary — you’ll often use it with apollo-server or graphql-yoga, not instead of them.

🛠️ Schema Definition: Code-First vs SDL-First

apollo-server traditionally uses SDL-first (Schema Definition Language) — you write .graphql files or template strings, then map resolvers separately.

// apollo-server: SDL + resolver map
const typeDefs = `
  type User {
    id: ID!
    name: String!
  }

  type Query {
    user(id: ID!): User
  }
`;

const resolvers = {
  Query: {
    user: (_, { id }) => getUserById(id)
  }
};

graphql-yoga doesn’t enforce a schema style — it accepts any valid GraphQLSchema object. So you can use SDL, code-first libraries like type-graphql, or even graphql-tools.

// graphql-yoga: Works with any schema source
import { schema } from './generated-schema'; // could be from type-graphql, nexus, etc.
const yoga = createYoga({ schema });

type-graphql is purely code-first. It uses decorators to generate both the schema and resolver logic from TypeScript classes, ensuring type safety and reducing duplication.

// type-graphql: Fully code-first
@InputType()
class UserInput {
  @Field()
  name: string;
}

@Resolver()
class UserResolver {
  @Mutation(() => User)
  createUser(@Arg('input') input: UserInput) {
    return saveUser(input);
  }
}

⚙️ Built-In Features: What Comes Out of the Box

apollo-server offers a rich plugin system (e.g., for caching, tracing, or custom directives) and deep Apollo Studio integration (metrics, schema validation, federated graph management). However, features like file uploads require extra setup (graphql-upload).

// apollo-server: File upload requires extra package
import { GraphQLUpload } from 'graphql-upload';

const typeDefs = `
  scalar Upload
  type Mutation {
    uploadFile(file: Upload!): String
  }
`;

graphql-yoga includes file uploads, GraphQL over GET, persisted operations, and error formatting by default. It also supports Envelop plugins for extending behavior without complex middleware.

// graphql-yoga: File uploads work out of the box
const typeDefs = `
  scalar File
  type Mutation {
    uploadFile(file: File!): String
  }
`;
// No extra config needed

type-graphql focuses solely on schema generation. It provides validation (via class-validator integration), authorization guards, and dependency injection, but nothing related to HTTP handling or execution context.

// type-graphql: Validation example
import { IsEmail } from 'class-validator';

@InputType()
class RegisterInput {
  @Field()
  @IsEmail()
  email: string;
}
// Validation runs automatically during resolver execution

🔌 Integration Patterns: How They Fit Together

In practice, many teams combine type-graphql with a server:

  • With Apollo Server: Use type-graphql to generate the schema, then pass it to ApolloServer.
import { buildSchema } from 'type-graphql';
import { ApolloServer } from 'apollo-server';

const schema = await buildSchema({ resolvers: [UserResolver] });
const server = new ApolloServer({ schema });
  • With GraphQL Yoga: Same idea, but plug into Yoga’s createYoga.
import { createYoga } from 'graphql-yoga';

const schema = await buildSchema({ resolvers: [UserResolver] });
const yoga = createYoga({ schema });

This combo gives you type-safe, decorator-based schema definition with the HTTP layer of your choice.

📦 Maintenance and Future Direction

As of 2024, apollo-server v4 is actively maintained, but the Apollo team has shifted focus toward Apollo Server Express and cloud-managed solutions. The core remains stable but sees fewer new features.

graphql-yoga is under active development by The Guild (creators of GraphQL Tools, Envelop, and Hive). It’s positioned as a modern, lightweight alternative with strong emphasis on spec compliance and developer experience.

type-graphql is stable and widely used, though its maintainer has indicated reduced activity. Many developers now consider alternatives like Nexus or GraphQL Code Generator for code-first workflows, but type-graphql remains a solid choice for decorator-based approaches.

🆚 Summary: When to Use Which

Concernapollo-servergraphql-yogatype-graphql
Primary RoleFull GraphQL serverFull GraphQL serverSchema generator (code-first)
Best ForApollo ecosystem, federationNew projects, minimal configTypeScript, decorator syntax
HTTP LayerBuilt-inBuilt-inNone (requires a server)
File UploadsRequires extra setupBuilt-inN/A
Schema StyleSDL-first (by convention)AnyCode-first only
Type SafetyManualManualAutomatic (via decorators)

💡 Final Guidance

  • If you’re already in the Apollo ecosystem or need federation, stick with apollo-server.
  • If you’re starting fresh and want simplicity, modern defaults, and zero-config DX, go with graphql-yoga.
  • If you love TypeScript decorators and want your schema and types to stay in sync automatically, use type-graphql — just remember to pair it with a server like Yoga or Apollo.

Don’t think of this as a three-way race. Often, the smartest move is to combine type-graphql with graphql-yoga — you get the best of both worlds: type-safe schema definition and a lean, modern server runtime.

How to Choose: graphql-yoga vs apollo-server vs type-graphql

  • graphql-yoga:

    Choose graphql-yoga if you want a lightweight, modern GraphQL server with zero-config setup, built-in support for GraphQL over HTTP (including persisted operations and file uploads), and seamless integration with frameworks like Next.js or Express. It’s ideal for new projects that prioritize developer ergonomics, spec compliance, and minimal boilerplate without sacrificing flexibility.

  • apollo-server:

    Choose apollo-server if you need deep integration with the Apollo ecosystem (like Apollo Studio, Federation, or Client DevTools), require mature plugin architecture, or are maintaining an existing Apollo-based backend. It’s well-suited for enterprise environments where tooling, observability, and federation are critical, though its configuration can be more verbose compared to newer alternatives.

  • type-graphql:

    Choose type-graphql if you’re using TypeScript and want to define your GraphQL schema and resolvers using class-based decorators, reducing the need to write SDL strings or separate resolver maps. It pairs well with any GraphQL server (like Apollo or Yoga) and is best suited for teams that value strong typing, code-first schema design, and automatic synchronization between TypeScript types and GraphQL schema.

README for graphql-yoga

GraphQL Yoga

Fully-featured GraphQL Server with focus on easy setup, performance & great developer experience
Go to documentation

npm bundlephobia minified size bundlephobia minified+zipped size bundlephobia treeshaking license

Quick start

Install

pnpm add graphql-yoga graphql

Start

Make a schema, create Yoga and start a Node server:

import { createServer } from 'node:http'
import { createSchema, createYoga } from 'graphql-yoga'

const yoga = createYoga({
  schema: createSchema({
    typeDefs: /* GraphQL */ `
      type Query {
        hello: String
      }
    `,
    resolvers: {
      Query: {
        hello: () => 'Hello from Yoga!'
      }
    }
  })
})

const server = createServer(yoga)

server.listen(4000, () => {
  console.info('Server is running on http://localhost:4000/graphql')
})

Overview

  • Easiest way to run a GraphQL server: Sensible defaults & includes everything you need with minimal setup (we also export a platform/env-agnostic handler so you can build your own wrappers easily).
  • Includes Subscriptions: Built-in support for GraphQL subscriptions using Server-Sent Events.
  • Compatible: Works with all GraphQL clients (Apollo, Relay, Urql...) and fits seamless in your GraphQL workflow.
  • WHATWG Fetch API: the core package depends on WHATWG Fetch API so it can run and deploy on any environment (Serverless, Workers, Deno, Node).
  • Easily Extendable: New GraphQL-Yoga support all envelop plugins.

Features

Documentation

Our documentation website will help you get started.

Examples

We've made sure developers can quickly start with GraphQL Yoga by providing a comprehensive set of examples. See all of them in the examples/ folder.

Comparison

Read more about how GraphQL Yoga compares to other servers in the ecosystem here.

Contributing

If this is your first time contributing to this project, please do read our Contributor Workflow Guide before you get started off.

For this project in particular, to get started on stage/2-failing-test:

  1. Install Node.js
  2. Run in your terminal: npm i -g pnpm@8 && pnpm install && pnpm build
  3. Add tests to packages/graphql-yoga/__tests__ using Jest APIs
  4. Run the tests with pnpm test

Feel free to open issues and pull requests. We're always welcome support from the community.

Code of Conduct

Help us keep Yoga open and inclusive. Please read and follow our Code of Conduct as adopted from Contributor Covenant.

License

MIT