{"id":10968,"library":"graphql-helix","title":"GraphQL Helix HTTP Server Utilities","description":"GraphQL Helix is a collection of framework and runtime agnostic utility functions designed for building GraphQL HTTP servers. It focuses on adherence to the GraphQL over HTTP specification, enabling a single HTTP endpoint for queries, mutations, subscriptions, and features like `@defer` and `@stream` directives. The package supports both server push and client pull paradigms for real-time data. It is known for its minimal footprint, having zero dependencies outside of `graphql-js` itself, and works across Node.js, Deno, and browser environments. The current stable version is 1.13.0, with minor and patch releases occurring frequently, as indicated by recent changes adding `extensions` and `operationName` to `ExecutionContext` and improving `accept` header handling. Its key differentiators include its agnosticism to specific HTTP frameworks and runtimes, strong HTTP-first and spec-compliant approach, and a focus on providing core abstractions without bloat or integrated platforms.","status":"active","version":"1.13.0","language":"javascript","source_language":"en","source_url":"https://github.com/contrawork/graphql-helix","tags":["javascript","graphql","graphiql","server","http","sse","multipart","defer","stream","typescript"],"install":[{"cmd":"npm install graphql-helix","lang":"bash","label":"npm"},{"cmd":"yarn add graphql-helix","lang":"bash","label":"yarn"},{"cmd":"pnpm add graphql-helix","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for GraphQL schema and execution logic.","package":"graphql","optional":false}],"imports":[{"note":"The library primarily uses ESM imports; CommonJS `require` might lead to issues in modern setups or be incompatible.","wrong":"const { processRequest } = require('graphql-helix');","symbol":"processRequest","correct":"import { processRequest } from 'graphql-helix';"},{"note":"This is a named export, not a default export.","wrong":"import getGraphQLParameters from 'graphql-helix';","symbol":"getGraphQLParameters","correct":"import { getGraphQLParameters } from 'graphql-helix';"},{"note":"Use direct named imports for clarity and tree-shaking benefits.","wrong":"import * as helix from 'graphql-helix'; helix.renderGraphiQL();","symbol":"renderGraphiQL","correct":"import { renderGraphiQL } from 'graphql-helix';"}],"quickstart":{"code":"import express from 'express';\nimport { buildSchema } from 'graphql';\nimport {\n  getGraphQLParameters,\n  processRequest,\n  renderGraphiQL,\n  shouldRenderGraphiQL,\n} from 'graphql-helix';\n\nconst schema = buildSchema(`\n  type Query {\n    hello: String\n  }\n  type Subscription {\n    greeting: String\n  }\n`);\n\nconst rootValue = {\n  hello: () => 'Hello GraphQL Helix!',\n  greeting: async function* () {\n    for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao']) {\n      yield { greeting: hi };\n      await new Promise(resolve => setTimeout(resolve, 500));\n    }\n  },\n};\n\nconst app = express();\napp.use(express.json());\n\napp.use('/graphql', async (req, res) => {\n  const request = {\n    body: req.body,\n    headers: req.headers,\n    method: req.method,\n    query: req.query,\n  };\n\n  if (shouldRenderGraphiQL(request)) {\n    res.send(renderGraphiQL());\n  } else {\n    const { operationName, query, variables } = getGraphQLParameters(request);\n\n    const result = await processRequest({\n      operationName,\n      query,\n      variables,\n      request,\n      schema,\n      contextFactory: () => ({ request }),\n      rootValue,\n    });\n\n    if (result.type === 'RESPONSE') {\n      result.headers.forEach(({ name, value }) => res.setHeader(name, value));\n      res.status(result.status);\n      res.json(result.payload);\n    } else if (result.type === 'MULTIPART_RESPONSE') {\n      res.writeHead(200, {\n        Connection: 'keep-alive',\n        'Content-Type': 'multipart/mixed; boundary=\"-\"',\n        'Transfer-Encoding': 'chunked',\n      });\n\n      req.on('close', () => {\n        result.unsubscribe();\n      });\n\n      res.write('---');\n\n      for await (const chunk of result.subscribe()) {\n        res.write(`\\r\\n${JSON.stringify(chunk)}\\r\\n---`);\n      }\n      res.end();\n    } else if (result.type === 'PUSH') {\n      res.writeHead(200, {\n        'Content-Type': 'text/event-stream',\n        Connection: 'keep-alive',\n        'Cache-Control': 'no-cache',\n      });\n\n      req.on('close', () => {\n        result.unsubscribe();\n      });\n\n      for await (const event of result.subscribe()) {\n        res.write(`data: ${JSON.stringify(event)}\\n\\n`);\n      }\n    }\n  }\n});\n\napp.listen(4000, () => console.log('GraphQL server running on http://localhost:4000/graphql'));","lang":"typescript","description":"This quickstart demonstrates setting up a basic GraphQL HTTP server using `graphql-helix` with Express, including support for queries, mutations (implied by `processRequest`), GraphiQL, and subscriptions via SSE."},"warnings":[{"fix":"Ensure your project is configured for ESM. Use `import ... from 'graphql-helix';` statements and consider setting `\"type\": \"module\"` in your `package.json`.","message":"GraphQL Helix moved to supporting only ESM (ECMAScript Modules) in its newer versions. While `require` might work in some transpiled environments, native ESM imports (`import`) are the intended and fully supported way to consume the library.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Install `graphql` explicitly: `npm install graphql@^15.3.0 || ^16.0.0` or `yarn add graphql@^15.3.0 || ^16.0.0`.","message":"The `graphql` package is a peer dependency. Installing `graphql-helix` without a compatible version of `graphql` will lead to runtime errors or module resolution issues.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Client applications should be updated to correctly handle `application/graphql+json` content types if they explicitly set the `Accept` header and rely on `application/json`.","message":"Since `graphql-helix@1.11.0`, clients accepting `application/graphql+json` (via the `Accept` header) will receive responses with `Content-Type: application/graphql+json` instead of `application/json` for spec compliance. Clients not specifying an `Accept` header still receive `application/json`.","severity":"gotcha","affected_versions":">=1.11.0"},{"fix":"Upgrade to `graphql-helix@1.10.1` or newer to ensure proper error handling and prevent information leaks in subscription resolvers.","message":"Prior to `graphql-helix@1.10.1`, errors thrown within `subscribe` handlers for `Subscription` root types were not properly handled and could expose internal error messages to clients.","severity":"gotcha","affected_versions":"<1.10.1"},{"fix":"Ensure you are using `graphql-helix@1.9.1` or later to correctly pass and access context within your GraphQL resolvers.","message":"Issues with context passing in `processRequest` (specifically related to `contextValue`) were patched in `graphql-helix@1.9.1`, potentially leading to `undefined` or incorrect context in resolvers for earlier versions.","severity":"gotcha","affected_versions":"<1.9.1"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Convert your consuming file to an ES Module by using `import ... from 'graphql-helix';` and ensure your `package.json` specifies `\"type\": \"module\"` or the file has a `.mjs` extension.","cause":"Attempting to use `require()` to import `graphql-helix` in a CommonJS module, but `graphql-helix` is an ES Module.","error":"Error [ERR_REQUIRE_ESM]: require() of ES Module .../node_modules/graphql-helix/lib/index.js from .../server.js not supported."},{"fix":"Ensure the `request` object you construct for `graphql-helix` contains `headers`, `method`, `query`, and `body` properties, even if some are empty objects or strings for simpler requests.","cause":"The `request` object passed to `getGraphQLParameters` or `processRequest` is missing the `headers` property or is `undefined`.","error":"TypeError: Cannot read properties of undefined (reading 'headers') at getGraphQLParameters"},{"fix":"Ensure your schema is correctly built using `buildSchema` or `makeExecutableSchema` (if using `@graphql-tools`) and passed as the `schema` option to `processRequest`.","cause":"`processRequest` received an invalid `schema` object; it must be a valid `GraphQLSchema` instance from `graphql-js`.","error":"Error: GraphQL.js cannot execute a request, because the provided schema is not a valid GraphQLSchema instance."},{"fix":"Ensure that your HTTP server implementation correctly awaits the `result.subscribe()` iterator for `MULTIPART_RESPONSE` or `PUSH` types, and properly terminates the response (e.g., `res.end()` for multipart or ensuring event stream ends).","cause":"Improper handling of asynchronous iterators for `@defer`/`@stream` or subscriptions, or not closing the HTTP connection properly after sending all parts.","error":"RangeError: Maximum call stack size exceeded (on multipart/mixed responses or SSE)"}],"ecosystem":"npm"}