DEV Community

Alex Spinov
Alex Spinov

Posted on

GraphQL Yoga Has a Free API — The Server That Runs Everywhere

GraphQL Yoga is The Guild's fully-featured GraphQL server — batteries-included, runs everywhere (Node, Deno, Bun, Cloudflare Workers, AWS Lambda), and it's completely free.

Why GraphQL Yoga Over Apollo Server?

  • Framework agnostic — runs on any JS runtime
  • Built-in subscriptions — WebSocket + SSE support
  • File uploads — multipart support out of the box
  • Envelop plugin system — composable middleware
  • Automatic persisted queries — performance optimization
  • Response caching — built-in HTTP cache
  • No Apollo dependency — lighter, faster, more flexible

Quick Start

npm install graphql-yoga graphql
Enter fullscreen mode Exit fullscreen mode
import { createServer } from "node:http";
import { createSchema, createYoga } from "graphql-yoga";

const yoga = createYoga({
  schema: createSchema({
    typeDefs: `
      type Query {
        hello(name: String!): String!
        users: [User!]!
      }

      type User {
        id: ID!
        name: String!
        email: String!
      }
    `,
    resolvers: {
      Query: {
        hello: (_, { name }) => `Hello, ${name}!`,
        users: () => [
          { id: "1", name: "Alice", email: "alice@example.com" },
          { id: "2", name: "Bob", email: "bob@example.com" },
        ],
      },
    },
  }),
});

const server = createServer(yoga);
server.listen(4000, () => {
  console.log("GraphQL: http://localhost:4000/graphql");
});
Enter fullscreen mode Exit fullscreen mode

Real-Time Subscriptions

import { createSchema, createYoga, createPubSub } from "graphql-yoga";

const pubSub = createPubSub();

const yoga = createYoga({
  schema: createSchema({
    typeDefs: `
      type Query {
        messages: [Message!]!
      }
      type Mutation {
        sendMessage(text: String!, author: String!): Message!
      }
      type Subscription {
        newMessage: Message!
      }
      type Message {
        id: ID!
        text: String!
        author: String!
        createdAt: String!
      }
    `,
    resolvers: {
      Query: {
        messages: () => messages,
      },
      Mutation: {
        sendMessage: (_, { text, author }) => {
          const message = {
            id: String(messages.length + 1),
            text,
            author,
            createdAt: new Date().toISOString(),
          };
          messages.push(message);
          pubSub.publish("newMessage", message);
          return message;
        },
      },
      Subscription: {
        newMessage: {
          subscribe: () => pubSub.subscribe("newMessage"),
          resolve: (payload) => payload,
        },
      },
    },
  }),
});
Enter fullscreen mode Exit fullscreen mode

File Uploads

const yoga = createYoga({
  schema: createSchema({
    typeDefs: `
      scalar File

      type Query { _: Boolean }

      type Mutation {
        uploadFile(file: File!): FileInfo!
      }

      type FileInfo {
        name: String!
        size: Int!
        type: String!
      }
    `,
    resolvers: {
      Mutation: {
        uploadFile: async (_, { file }) => {
          const buffer = await file.arrayBuffer();
          // Save to disk, S3, etc.
          return {
            name: file.name,
            size: file.size,
            type: file.type,
          };
        },
      },
    },
  }),
});
Enter fullscreen mode Exit fullscreen mode

Deploy Everywhere

// Cloudflare Workers
export default createYoga({ schema });

// AWS Lambda
import { createYoga } from "graphql-yoga";
export const handler = createYoga({ schema });

// Deno
import { serve } from "https://deno.land/std/http/server.ts";
serve(createYoga({ schema }));

// Bun
Bun.serve(createYoga({ schema }));

// Express
import express from "express";
const app = express();
app.use("/graphql", createYoga({ schema }));
Enter fullscreen mode Exit fullscreen mode

Envelop Plugins

import { createYoga } from "graphql-yoga";
import { useGraphQLJit } from "@envelop/graphql-jit";
import { useResponseCache } from "@envelop/response-cache";
import { useRateLimiter } from "@envelop/rate-limiter";
import { useAuth0 } from "@envelop/auth0";

const yoga = createYoga({
  schema,
  plugins: [
    useGraphQLJit(),        // 10x faster query execution
    useResponseCache({      // HTTP caching
      ttl: 60_000,
    }),
    useRateLimiter({        // Rate limiting
      identifyFn: (ctx) => ctx.request.headers.get("x-forwarded-for"),
    }),
    useAuth0({              // Authentication
      domain: "your-domain.auth0.com",
      audience: "your-api",
    }),
  ],
});
Enter fullscreen mode Exit fullscreen mode

GraphQL Yoga vs Apollo Server vs Mercurius

Feature GraphQL Yoga Apollo Server Mercurius
Runtime Any JS runtime Node.js Fastify only
Subscriptions Built-in (WS + SSE) Separate package Built-in
File uploads Built-in Separate package Plugin
Caching Envelop plugin Apollo Cache Built-in
Plugin system Envelop Apollo plugins Fastify plugins
Bundle size ~30KB ~200KB ~50KB
Federation Via plugin Built-in Via plugin

Need to scrape data from any website and get it in structured JSON? Check out my web scraping tools on Apify — no coding required, results in minutes.

Have a custom data extraction project? Email me at spinov001@gmail.com — I build tailored scraping solutions for businesses.

Top comments (0)