GraphQL-WS is a comprehensive GraphQL over WebSocket implementation that enables real-time GraphQL subscriptions, queries, and mutations over WebSocket connections. It provides both client and server implementations that are fully compliant with the GraphQL over WebSocket Protocol, featuring zero dependencies, lazy connection handling, and simple integration patterns.
npm install graphql-wsimport { createClient, makeServer } from "graphql-ws";For client-only usage:
import { createClient } from "graphql-ws/client";CommonJS:
const { createClient, makeServer } = require("graphql-ws");import { createClient } from "graphql-ws";
const client = createClient({
url: "ws://localhost:4000/graphql",
});
// Subscribe to a GraphQL subscription
const unsubscribe = client.subscribe(
{
query: "subscription { messageAdded { id content } }",
},
{
next: (data) => console.log("Received:", data),
error: (err) => console.error("Error:", err),
complete: () => console.log("Subscription completed"),
}
);
// Later, unsubscribe
unsubscribe();import { makeServer } from "graphql-ws";
import { WebSocketServer } from "ws";
const server = makeServer({
schema, // Your GraphQL schema
});
const wsServer = new WebSocketServer({ port: 4000, path: "/graphql" });
wsServer.on("connection", (socket, request) => {
const closed = server.opened(socket, { socket, request });
socket.once("close", closed);
});GraphQL-WS is designed around several key components:
Core client functionality for establishing WebSocket connections and managing GraphQL subscriptions with comprehensive configuration options.
function createClient<P = Record<string, unknown>>(
options: ClientOptions<P>
): Client;
interface Client extends Disposable {
on<E extends Event>(event: E, listener: EventListener<E>): () => void;
subscribe<Data = Record<string, unknown>, Extensions = unknown>(
payload: SubscribePayload,
sink: Sink<FormattedExecutionResult<Data, Extensions>>
): () => void;
iterate<Data = Record<string, unknown>, Extensions = unknown>(
payload: SubscribePayload
): AsyncIterableIterator<FormattedExecutionResult<Data, Extensions>>;
terminate(): void;
}Server-side GraphQL over WebSocket implementation with extensive customization hooks and execution control.
function makeServer<P = Record<string, unknown>, E = unknown>(
options: ServerOptions<P, E>
): Server<E>;
interface Server<E = unknown> {
opened(
socket: WebSocket,
ctxExtra: E
): (code?: number, reason?: string) => Promise<void>;
}Specialized adapters for integrating with different WebSocket server implementations across multiple JavaScript runtimes.
// ws adapter
function useServer<P = Record<string, unknown>, E = unknown>(
options: ServerOptions<P, Extra & Partial<E>>,
ws: WebSocketServer,
keepAlive?: number
): Disposable;
// uWebSockets.js adapter
function makeBehavior<P = Record<string, unknown>, E = unknown>(
options: ServerOptions<P, Extra & Partial<E>>,
behavior?: uWS.WebSocketBehavior<unknown>,
keepAlive?: number
): uWS.WebSocketBehavior<unknown>;Shared types, constants, and utilities used by both client and server implementations, including the complete GraphQL over WebSocket Protocol message types.
const GRAPHQL_TRANSPORT_WS_PROTOCOL = "graphql-transport-ws";
enum CloseCode {
InternalServerError = 4500,
BadRequest = 4400,
Unauthorized = 4401,
Forbidden = 4403,
// ... additional codes
}
enum MessageType {
ConnectionInit = "connection_init",
Subscribe = "subscribe",
Next = "next",
Error = "error",
Complete = "complete",
// ... additional types
}GraphQL-WS provides comprehensive error handling through:
Common error scenarios include connection timeouts, authentication failures, and protocol violations, all with appropriate close codes and error reporting.