{"id":15632,"library":"graphql-ws","title":"GraphQL over WebSocket Protocol Client & Server","description":"graphql-ws is a JavaScript/TypeScript library that provides a coherent, zero-dependency, and lazy implementation of the GraphQL over WebSocket Protocol for both server and client applications. The current stable version is 6.0.8, with a development cadence that includes frequent patch releases for bug fixes and minor enhancements. Major versions, like v6, typically introduce targeted breaking changes related to API adjustments or adapter integrations. A crucial differentiator is its strict adherence to the modern GraphQL over WebSocket Protocol, which makes it explicitly incompatible with the older, deprecated `subscriptions-transport-ws` library and its distinct protocol. The library offers flexible integration with various Node.js WebSocket server implementations such as `ws`, Fastify's `@fastify/websocket`, and `crossws`, catering to diverse server environments.","status":"active","version":"6.0.8","language":"javascript","source_language":"en","source_url":"https://github.com/enisdenjo/graphql-ws","tags":["javascript","protocol","graphql","transport","subscriptions","websockets","server","client","observables","typescript"],"install":[{"cmd":"npm install graphql-ws","lang":"bash","label":"npm"},{"cmd":"yarn add graphql-ws","lang":"bash","label":"yarn"},{"cmd":"pnpm add graphql-ws","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Optional peer dependency for integrating with Fastify servers for WebSocket handling.","package":"@fastify/websocket","optional":true},{"reason":"Optional peer dependency for integrating with crossws, a universal WebSocket adapter.","package":"crossws","optional":true},{"reason":"Required peer dependency for GraphQL execution, supporting versions ^15.10.1 || ^16.","package":"graphql","optional":false},{"reason":"Optional peer dependency for integrating with the 'ws' WebSocket server (Node.js native WebSocket).","package":"ws","optional":true}],"imports":[{"note":"Primarily for client-side usage to connect to a GraphQL WebSocket server. For Node.js client environments, you might need to specify `webSocketImpl: WebSocket` if `WebSocket` is not globally available.","wrong":"const createClient = require('graphql-ws').createClient;","symbol":"createClient","correct":"import { createClient } from 'graphql-ws';"},{"note":"Used for integrating graphql-ws with the `ws` WebSocket server library. In v6 and later, the import path for adapters changed from `/lib/use/` to `/use/`.","wrong":"import { useServer } from 'graphql-ws/use/ws'; // Incorrect path pre-v6","symbol":"useServer","correct":"import { useServer } from 'graphql-ws/lib/use/ws';"},{"note":"Used for integrating graphql-ws with Fastify and its `@fastify/websocket` plugin. Similar to `useServer`, the import path structure changed in v6.","wrong":"import { makeHandler } from 'graphql-ws/use/@fastify/websocket'; // Incorrect path pre-v6","symbol":"makeHandler","correct":"import { makeHandler } from 'graphql-ws/lib/use/@fastify/websocket';"}],"quickstart":{"code":"import { createServer } from 'http';\nimport { WebSocketServer } from 'ws';\nimport { useServer } from 'graphql-ws/lib/use/ws';\nimport { makeExecutableSchema } from '@graphql-tools/schema';\nimport { PubSub } from 'graphql-subscriptions';\nimport { createClient } from 'graphql-ws';\n\n// --- Server Setup ---\nconst pubsub = new PubSub();\nconst HELLO_EVENT = 'hello_event';\n\nconst typeDefs = `\n  type Query {\n    hello: String\n  }\n  type Subscription {\n    greetings: String\n  }\n`;\n\nconst resolvers = {\n  Query: {\n    hello: () => 'world',\n  },\n  Subscription: {\n    greetings: {\n      subscribe: () => pubsub.asyncIterator(HELLO_EVENT),\n      resolve: (payload) => payload.greetings,\n    },\n  },\n};\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n\nconst server = createServer((req, res) => {\n  res.writeHead(404);\n  res.end();\n});\n\nconst wsServer = new WebSocketServer({\n  server,\n  path: '/graphql',\n});\n\nuseServer(\n  {\n    schema,\n    context: async (ctx) => {\n      // Example: access the websocket instance through ctx.extra.socket in v6+\n      // const socket = ctx.extra.socket;\n      return { currentUser: 'someUser' };\n    }\n  },\n  wsServer\n);\n\nserver.listen(4000, () => {\n  console.log('GraphQL server running on http://localhost:4000/graphql');\n  console.log('WebSocket server running on ws://localhost:4000/graphql');\n\n  let count = 0;\n  setInterval(() => {\n    pubsub.publish(HELLO_EVENT, { greetings: `Hello from server! (${count++})` });\n  }, 2000);\n});\n\n// --- Client Setup ---\nconst client = createClient({\n  url: 'ws://localhost:4000/graphql',\n  webSocketImpl: WebSocket, // Required for Node.js environments; in browser, it's global\n  on: {\n    connected: () => console.log('Client connected to server.'),\n    closed: (event) => console.log(`Client disconnected: ${event.code} - ${event.reason}`),\n    error: (err) => console.error('Client error:', err),\n  },\n});\n\nasync function subscribeToGreetings() {\n  const onNext = ({ data }) => {\n    console.log('Received greeting:', data.greetings);\n  };\n\n  const onError = (err) => {\n    console.error('Subscription error:', err);\n  };\n\n  const onComplete = () => {\n    console.log('Subscription complete.');\n  };\n\n  const unsubscribe = client.subscribe(\n    {\n      query: `subscription { greetings }`,\n    },\n    {\n      next: onNext,\n      error: onError,\n      complete: onComplete,\n    }\n  );\n\n  setTimeout(() => {\n    unsubscribe();\n    console.log('Unsubscribed from greetings.');\n    client.dispose(); // Close the WebSocket connection\n    server.close(); // Close the HTTP/WebSocket server\n  }, 10000);\n}\n\n// Run 'npm install ws graphql-subscriptions @graphql-tools/schema graphql' first\nsubscribeToGreetings().catch(console.error);","lang":"typescript","description":"Demonstrates setting up a basic GraphQL server with subscriptions using `ws` and `graphql-ws`, along with a client that connects and subscribes to a real-time greeting stream. Requires `ws`, `graphql-subscriptions`, `@graphql-tools/schema`, and `graphql` as peer dependencies."},"warnings":[{"fix":"If using `@fastify/websocket` adapter, change `ctx.extra.connection` to `ctx.extra.socket` within your `makeHandler` options.","message":"Starting from v6, for the `@fastify/websocket` adapter, the `connection` property in `ctx.extra` has been renamed to `socket`. This change requires updating any server-side code that accesses the raw WebSocket instance via the context.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Update your import statements to remove the `/lib` segment: `import { useServer } from 'graphql-ws/use/ws';`","message":"The import paths for adapters like `useServer` (for `ws`) and `makeHandler` (for `@fastify/websocket`) changed from `graphql-ws/lib/use/<adapter>` to `graphql-ws/use/<adapter>` in v6.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Ensure both server and client use `graphql-ws` and adhere to the GraphQL over WebSocket Protocol. Do not attempt to use `subscriptions-transport-ws` with `graphql-ws`.","message":"graphql-ws is explicitly not compatible with the older, deprecated `subscriptions-transport-ws` library due to different WebSocket subprotocols. Mixing them will lead to connection failures.","severity":"breaking","affected_versions":"All versions"},{"fix":"Upgrade your Node.js runtime environment to version 20 or higher.","message":"Minimum Node.js version supported is 20. Attempts to run on older Node.js versions will result in runtime errors.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"If you intend to use `graphql-ws` with `uWebSockets.js`, install `uWebSockets.js` manually alongside `graphql-ws`. Otherwise, migrate to a supported peer dependency like `ws`, `@fastify/websocket`, or `crossws`.","message":"The `uWebSockets.js` library was removed from `graphql-ws`'s peer dependencies in v6.0.7 because it's no longer on NPM. While it can still be used if installed manually, `npm` might report warnings or issues if not handled carefully.","severity":"gotcha","affected_versions":">=6.0.7"},{"fix":"Adjust callback signatures for these hooks to expect only `id` and the relevant `payload` portion, rather than the complete `SubscribeMessage` or `ExecutionResult`.","message":"The `onSubscribe`, `onOperation`, `onError`, `onNext`, and `onComplete` hooks in `useServer` no longer receive the full message object, only the ID and the relevant payload part. This simplifies the API and avoids redundant serialization.","severity":"gotcha","affected_versions":">=6.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure your GraphQL WebSocket server is actively running and accessible at `ws://localhost:4000/graphql`. Check server logs for errors and firewall configurations.","cause":"The WebSocket server is not running, not listening on the specified port/path, or a firewall is blocking the connection.","error":"WebSocket connection to 'ws://localhost:4000/graphql' failed: WebSocket opening handshake timed out"},{"fix":"Verify that your client is using the correct subprotocol (`graphql-ws`) and sending a valid `ConnectionInit` message. On the server, ensure proper WebSocket upgrade logic is in place for the specified path, and check `onConnect` hooks for rejection conditions.","cause":"The server received a WebSocket connection request but rejected it, often due to an incorrect subprotocol or an invalid connection initialization payload from the client. This can also occur if the HTTP server is serving the same path as the WebSocket server without proper upgrade handling.","error":"WebSocket connection to 'ws://localhost:4000/graphql' failed: Error during WebSocket handshake: Unexpected response code: 400"},{"fix":"Update the import path to `import { useServer } from 'graphql-ws/use/ws';` (remove `/lib`).","cause":"This error typically occurs in v6+ when an old import path for adapters is used. The `/lib` segment was removed from the import paths.","error":"Cannot find module 'graphql-ws/lib/use/ws' or its corresponding type declarations."},{"fix":"Ensure you are using `import { createClient } from 'graphql-ws';` in ESM contexts. If strictly in CommonJS (though less common for client), use dynamic import or check your bundler/TypeScript configuration for module interop issues.","cause":"This usually indicates a CommonJS `require()` style import is being used in an ESM context, or vice-versa, leading to incorrect module resolution, especially with `graphql-ws`'s dual package setup.","error":"TypeError: (0 , graphql_ws__WEBPACK_IMPORTED_MODULE_0__.createClient) is not a function"}],"ecosystem":"npm"}