GraphQL SSE Library

2.6.0 · active · verified Tue Apr 21

graphql-sse is a lightweight, zero-dependency (aside from a `graphql` peer dependency) library that enables GraphQL operations, particularly subscriptions, over the Server-Sent Events (SSE) protocol. It provides both server-side handler utilities and a client for consuming SSE streams. The current stable version is 2.6.0, with releases occurring semi-regularly, focusing on bug fixes, feature enhancements like dynamic client URLs, and new framework integrations (e.g., Koa, Fastify, Express adapters). Its key differentiator is its exclusive use of SSE, making it HTTP/1 safe and suitable for environments where WebSockets might be problematic, offering a robust alternative to `graphql-ws` for subscription-heavy applications without requiring a separate WebSocket server infrastructure. It is designed for simplicity and direct integration with existing HTTP servers.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates setting up a GraphQL SSE server with Express and then connecting to it with the `graphql-sse` client to run a real-time subscription for a countdown.

import express from 'express';
import { createHandler } from 'graphql-sse';
import { useServer } from 'graphql-sse/use/express'; // Or use/fastify, use/koa, etc.
import { makeExecutableSchema } from '@graphql-tools/schema';
import { createClient } from 'graphql-sse';

// --- Server Setup ---
const typeDefs = `
  type Query {
    hello: String
  }
  type Subscription {
    countdown(from: Int!): Int!
  }
`;

const resolvers = {
  Query: {
    hello: () => 'world',
  },
  Subscription: {
    countdown: {
      subscribe: async function* (_, { from }: { from: number }) {
        for (let i = from; i >= 0; i--) {
          await new Promise((resolve) => setTimeout(resolve, 1000));
          yield { countdown: i };
        }
      },
    },
  },
};

const schema = makeExecutableSchema({ typeDefs, resolvers });
const handler = createHandler({ schema });

const app = express();
app.use('/graphql/sse', useServer({ handler })); // Mount the SSE handler

app.get('/health', (req, res) => res.send('OK'));

const PORT = process.env.PORT || 4000;
app.listen(PORT, () => {
  console.log(`Server listening on http://localhost:${PORT}/graphql/sse`);
});

// --- Client Setup ---
const client = createClient({
  url: `http://localhost:${PORT}/graphql/sse`
});

async function runSubscription() {
  const query = `
    subscription Countdown($from: Int!) {
      countdown(from: $from)
    }
  `;

  const input = { from: 5 };

  console.log('\nClient: Subscribing to countdown...');
  try {
    for await (const result of client.iterate(query, input)) {
      console.log('Client: Received:', result.data?.countdown);
      if (result.data?.countdown === 0) {
        console.log('Client: Countdown finished.');
        break;
      }
    }
  } catch (error) {
    console.error('Client: Subscription error', error);
  }
}

// Start the client subscription after a short delay to allow server to boot
setTimeout(runSubscription, 2000);

view raw JSON →