# graphql-zeus

> Generate Client Library for GraphQL Schema

Latest version **7.2.1** (published 2026-04-08) · MIT license · 0 weekly downloads

## Install

```sh
npm install graphql-zeus
pnpm add graphql-zeus
yarn add graphql-zeus
bun add graphql-zeus
```

Provides the command `zeus`.

## Health

**Score 55/100 (C)** — status: active.

Positive: has types; esm support; no vulnerabilities.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 7.2.1 |
| Published | 2026-04-08 |
| First published | 2019-07-16 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 7 |
| Unpacked size | 145.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1977 |
| Author | GraphQL Editor, Artur Czemiel |
| Maintainers | arturczemiel, ania-aexol, aexol-office, kamil-aexol, slothking |

## Links

- npm: https://www.npmjs.com/package/graphql-zeus
- Repository: https://github.com/graphql-editor/graphql-zeus
- Homepage: https://graphqleditor.com
- Issues: https://github.com/graphql-editor/graphql-zeus.git
- npm.io page: https://npm.io/package/graphql-zeus

## Dependencies (7)

- [yargs](https://npm.io/package/yargs.md) ^16.1.1
- [prompts](https://npm.io/package/prompts.md) ^2.4.2
- [cross-fetch](https://npm.io/package/cross-fetch.md) ^3.0.4
- [config-maker](https://npm.io/package/config-maker.md) ^0.0.6
- [graphql-js-tree](https://npm.io/package/graphql-js-tree.md) ^3.0.4
- [graphql-zeus-core](https://npm.io/package/graphql-zeus-core.md) ^7.2.1
- [graphql-zeus-jsonschema](https://npm.io/package/graphql-zeus-jsonschema.md) ^7.2.1

## Recent versions

- 7.2.1 (latest) — 2026-04-08
- 5.0.0-rc-8 (tree) — 2022-04-17
- 3.0.0-19 (beta) — 2021-02-09
- 7.2.0 — 2026-02-20
- 7.1.9 — 2025-12-20
- 7.1.8 — 2025-12-05
- 7.1.6 — 2025-11-27
- 7.1.5 — 2025-11-24
- 7.1.4 — 2025-10-24
- 7.1.3 — 2025-09-30
- 7.1.2 — 2025-09-30
- 7.1.1 — 2025-09-29
- 7.1.0 — 2025-09-19
- 7.0.10 — 2025-09-19
- 7.0.9 — 2025-09-19
- … 221 more at https://npm.io/package/graphql-zeus/versions

## README

# Zeus | GraphQL TypeScript generator

Strongly Typed GraphQL from the team at [GraphQL Editor](https://graphqleditor.com/)

GraphQL Zeus is the absolute best way to interact with your GraphQL endpoints in a type-safe way. Zeus uses your schema to generate Typescript types and strongly typed clients to unlock the power, efficiency, productivity and safety of Typescript on your GraphQL requests.

## LLM Quickstart

- Generate client code from a schema or URL
  - `npx graphql-zeus https://your.graphql/endpoint ./zeus --typescript`
  - Outputs `./zeus/index.ts` (+ `./zeus/typedDocumentNode.ts`)
- Use the generated helpers in your app (based on examples/typescript-node/src/index.ts)

```ts
// From the generated folder
import {
  Gql,
  Zeus,
  $,
  Selector,
  GraphQLTypes,
  InputType,
  fields,
  ZeusScalars,
  Thunder,
} from './zeus';
import { typedGql } from './zeus/typedDocumentNode';

// Query/mutation with variables (typed end-to-end)
const addCard = await Gql('mutation')(
  {
    addCard: [
      { card: { Attack: $('Attack', 'Int!'), Defense: 2, name: 'AA', description: 'DD' } },
      { id: true, info: true },
    ],
  },
  { variables: { Attack: 1 } },
);

// Build reusable selections and infer types
const q = Selector('Query')({ drawCard: { id: true, Attack: true } });
type DrawCard = InputType<GraphQLTypes['Query'], typeof q>;

// Spread all scalar fields of a type
const res = await Gql('query')({ drawCard: { ...fields('Card') } });

// Aliases and raw query string generation
const queryStr = Zeus('query', { __alias: { myCards: { listCards: { name: true } } } });

// TypedDocumentNode for Apollo/urql
const byId = typedGql('query')({ cardById: [{ cardId: $('id', 'String!') }, { name: true }] });

// Custom fetch while keeping response types
const thunder = Thunder(async (query) => {
  const r = await fetch('https://your.graphql/endpoint', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query }),
  });
  const j = await r.json();
  return j.data;
});
const data = await thunder('query')({ drawCard: { id: true } });

// Scalar encoders/decoders in one place
const scalars = ZeusScalars({
  JSON: { encode: JSON.stringify, decode: (e) => e as unknown },
});
await Gql('query', { scalars })({ drawCard: { info: true } });
```

Notes
- Generated helpers are framework-agnostic and work in Node, browser and RN.
- See a full working usage in `examples/typescript-node/src/index.ts`.

## Features

⚡️ Types mapped from your schema\
⚡️ Works with Apollo Client, React Query, Stucco Subscriptions _(\*more coming soon...)_\
⚡️ Works with Subscriptions\
⚡️ Allows inferring complex response types\
⚡️ Creates reusable selection sets (like fragments) for use across multiple queries\
⚡️ Supports GraphQL Unions, Interfaces, Aliases and Variables\
⚡️ Handles **massive** schemas\
⚡️ Supports Browsers, Node.js and React Native in Javascript and Typescript\
⚡️ Has a schema downloader\
⚡️ Supports JSON schema generation\

## Getting Started | Zeus GraphQL TypeScript generator

Use the Zeus CLI to generate types and GraphQL clients based on your schema, which you can then import into your projects to autocomplete, query and use GraphQL responses in a type-safe way.

# Zeus Spec

To return the promise of type query for data object:

```
PROMISE_RETURNING_OBJECT = Chain.[OPERATION_NAME]({
    ...FUNCTION_FIELD_PARAMS
})(
    ...QUERY_OBJECT
).then ( RESPONSE_OBJECT => RESPONSE_OBJECT[OPERATION_FIELD] )
```

The simple command for object function params:

```
FUNCTION_FIELD_PARAMS = {
  KEY: VALUE
}
```

Query object:

```
QUERY_OBJECT = {
    ...RETURN_PARAMS
}
```

Return params is an object containing RETURN_KEY - true if it is a `scalar`, RETURN_PARAMS if `type`. Otherwise it is a function where you pass field params and type return params.

```
RETURN_PARAMS = {
    RETURN_KEY: true,
    RETURN_KEY: {
        ...RETURN_PARAMS
    },
    RETURN_FUNCTION_KEY:[
        {
            ...FUNCTION_FIELD_PARAMS
        },
        {
            ...RETURN_PARAMS
        }
    ]
}
```

### Use Alias Spec

```
RETURN_PARAMS = {
  __alias: RETURN_PARAMS
}
```

Access aliased operation in a type-safe way:

```
PROMISE_RETURNING_OBJECT[ALIAS_STRING]
```

## Installation

```sh
$ npm i -g graphql-zeus
# OR
# yarn global add graphql-zeus
```

You can also install it locally to a project and then use it as an npm or yarn script command or with `npx` or `yarn` directly eg:

```sh
$ npx zeus schema.graphql ./
# OR
# yarn zeus schema.graphql ./
```

## TypeScript

Zeus is TypeScript native, you can refer to imported types directly from the generated output of the CLI

```sh
$ zeus schema.graphql ./
```

## Usage

To generate clients simply run this command:

| for NodeJS:                        | for React Native:          |
| ---------------------------------- | -------------------------- |
| `$ zeus schema.graphql ./  --node` | `$ zeus schema.graphql ./` |

## Other CLI Options

Here's a list of commands for other options and flags you can use with Zeus:  
_for a demo URL you can use:_ `https://faker.graphqleditor.com/a-team/olympus/graphql`

| function:                               | command:                                                                |
| --------------------------------------- | ----------------------------------------------------------------------- |
| Open Zeus CLI help                      | `$ zeus help`                                                           |
| Specify an output folder                | `$ zeus schema.graphql ./generated`                                     |
| Output Typescript **only**              | `$ zeus schema.graphql ./ --typescript`                                 |
| Load schema from a URL                  | `$ zeus https://example.com ./`                                         |
| Download and save your schema locally   | `$ zeus https://example.com ./ --graphql=generated`                     |
| Generate and save a JSON schema locally | `$ zeus https://example.com ./ --graphql=generated`                     |
| Add a header value                      | `$ zeus https://example.com ./ --header=Authorization:myNiceAuthHeader` |

### Tip:

Add a script entry in your `package.json` file for quickly calling Zeus generation:

```json
"scripts": {
//...
"generate": "zeus https://faker.graphqleditor.com/a-team/olympus/graphql zeusGenerated --typescript --header='My-Auth-Secret:JsercjjJY5MmghtHww6UF' --apollo"
},
```

## Demo Endpoint

All demo code here is using the demo GraphQL endpoint of [Olympus Cards](https://app.graphqleditor.com/a-team/olympus){rel="nofollow"} built with [GraphQL Editor](https://graphqleditor.com/). Feel free to check out the [GraphiQL interface](https://faker.graphqleditor.com/a-team/olympus/graphql){rel="nofollow"} too.

## Query With Zeus Chain Client

You can now use the Zeus `Chain` client from the generated output to make type-safe queries and mutations to your endpoint and receive type-safe responses.

```ts
import { Chain } from './zeus';

// Create a Chain client instance with the endpoint
const chain = Chain('https://faker.graphqleditor.com/a-team/olympus/graphql');

// Query the endpoint with Typescript autocomplete for arguments and response fields
const listCardsAndDraw = await chain('query')({
  cardById: [
    {
      cardId: 'da21ce0a-40a0-43ba-85c2-6eec2bf1ae21',
    },
    {
      name: true,
      description: true,
    },
  ],
  listCards: {
    name: true,
    skills: true,
    attack: [
      {
        cardID: [
          '66c1af53-7d5e-4d89-94b5-1ebf593508f6',
          'fc0e5757-4d8a-4f6a-a23b-356ce167f873',
        ],
      },
      {
        name: true,
      },
    ],
  },
  drawCard: {
    name: true,
    skills: true,
    Attack: true,
  },
});
// listCardsAndDraw is now typed as the response of the query.
```

When querying a GraphQL field that takes an argument like `cardById` above, the fields are defined in terms of a tuple for example: cardById: `[ {...arguments} , {...response_selection_set} ]` and the equivalent in gql syntax would be:

```text
cardById (cardId: "da21ce0a-40a0-43ba-85c2-6eec2bf1ae21") {
  name
  description
}
```

For fields that have no argument, they receive only the response selection set object values.

Note: `Chain` will also accept a second argument of fetch-like options to configure the client with properties such as `credentials`, `mode`, `headers` etc...

Note: There is also an exported Zeus `Gql` convenience function in a `Chain` client, pre-configured with the endpoint specified in the CLI.

## Listen on a WebSocket - GraphQL Subscriptions

Use the Zeus `Subscription` client creator in your generated output to create WebSocket connections to your GraphQL socket.

```ts
import { Subscription } from './zeus';

// Create a Subscription client instance with the endpoint
const sub = Subscription(
  'https://faker.graphqleditor.com/a-team/olympus/graphql',
);

// Call the client instance and listen for responses
sub('subscription')({
  deck: {
    id: true,
  },
}).on((response) => {
  console.log(response.deck);
});
```

# Selectors | Zeus GraphQL TypeScript generator

### Generate Reusable Selection Sets

In TypeScript Zeus can help you make type-safe Zeus selection sets to reuse across queries.

```typescript
import { Selector, Chain } from './zeus';

const chain = Chain('https://faker.graphqleditor.com/a-team/olympus/graphql');

const cardSelector = Selector('Card')({
  name: true,
  description: true,
  Attack: true,
  skills: true,
  Defense: true,
  cardImage: {
    key: true,
    bucket: true,
  },
});

const queryWithSelectionSet = await chain('query')({
  drawCard: cardSelector,
});
```

### FromSelector: Infer Types From Selectors

Use `FromSelector` to derive a concrete TypeScript type from a selector for a specific GraphQL type.

```ts
import { Selector, FromSelector } from './zeus';

const nameableSelector = Selector('Nameable')({
  __typename: true,
  name: true,
  '...on Card': { description: true },
  '...on EffectCard': { effectSize: true },
  '...on CardStack': { cards: { id: true } },
});

type Nameable = FromSelector<typeof nameableSelector, 'Nameable'>;

// Discriminate on __typename safely
const handle = (n: Nameable) => {
  if (n.__typename === 'Card') n.description;
  if (n.__typename === 'EffectCard') n.effectSize;
  if (n.__typename === 'CardStack') n.cards;
};
```

### Composing Selectors

You can pass reusable selections around using `ComposableSelector` to compose queries dynamically.

```ts
import { Gql, ComposableSelector } from './zeus';

const withCardById = <T extends ComposableSelector<'Card'>>(id: string, selection: T) =>
  Gql('query')({
    cardById: [{ cardId: id }, selection],
  });

// usage
const r1 = await withCardById('1', { id: true });
const r2 = await withCardById('1', { Attack: true, Defense: true });
```

You can also build on existing selections by spreading:

```ts
const baseCard = Selector('Card')({ id: true, name: true });
const detailedCard = Selector('Card')({ ...baseCard, Attack: true, Defense: true });
```

### FromSelector + ZeusScalars

When you use custom scalar encoders/decoders via `ZeusScalars`, you can thread that information into `FromSelector` so fields resolve to their decoded types.

```ts
import { ZeusScalars, Selector, FromSelector } from './zeus';

const scalars = ZeusScalars({
  JSON: { encode: JSON.stringify, decode: (e) => e as { power: number } },
  ID: { decode: (e) => Number(e) },
});

const cardSel = Selector('Card')({ id: true, info: true }); // info: JSON

type CardWithScalars = FromSelector<typeof cardSel, 'Card', typeof scalars>;
// CardWithScalars['info'] is now { power: number }
```

### Inferring the response type

Sometimes you might want to infer the response type. In that case, it is best to use selectors:

```tsx
import { Selector, InputType, GraphQLTypes } from './zeus';

export const drawCardQuery = Selector("Query"){
  drawCard: {
    Attack: true,
    Children: true,
    id: true,
  },
});

type InferredResponseType = InputType<GraphQLTypes['Query'], typeof drawCardQuery>;
```

# Custom fetch

Use the Zeus `Thunder` to get total control over the fetch function and ensure you won't lose the result type. ⚡️

```typescript
import { Thunder } from './zeus';

// Create thunder fetch client with endpoint, options and response handlers
const thunder = Thunder(async (query) => {
  const response = await fetch(
    'https://faker.graphqleditor.com/a-team/olympus/graphql',
    {
      body: JSON.stringify({ query }),
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    },
  );

  if (!response.ok) {
    return new Promise((resolve, reject) => {
      response
        .text()
        .then((text) => {
          try {
            reject(JSON.parse(text));
          } catch (err) {
            reject(text);
          }
        })
        .catch(reject);
    });
  }

  const json = await response.json();

  return json.data;
});

// Call thunder client with type-safe arguments, fields and get type-safe result type
const listCardsAndDraw = await thunder('query')({
  cardById: [
    {
      cardId: 'sdsd',
    },
    {
      description: true,
    },
  ],
  listCards: {
    name: true,
    skills: true,
    attack: [
      { cardID: ['s', 'sd'] },
      {
        name: true,
      },
    ],
  },
  drawCard: {
    name: true,
    skills: true,
    Attack: true,
  },
});
```

# Interfaces and Unions

### GraphQL Unions

You can use Zeus with [GraphQL Unions](https://spec.graphql.org/June2018/#sec-Unions):

```typescript
const { drawChangeCard } = await chain('query')({
  drawChangeCard: {
    __typename: true,
    '...on EffectCard': {
      effectSize: true,
      name: true,
    },
    '...on SpecialCard': {
      effect: true,
      name: true,
    },
  },
});
```

and it will give you this response:

```json
{
  "effectSize": 195.99532210956377,
  "name": "Destinee",
  "__typename": "EffectCard"
}
```

### GraphQL Interfaces

Zeus also works with [GraphQL Interfaces](http://spec.graphql.org/June2018/#sec-Interfaces)

```typescript
const { nameables } = await Gql('query')({
  nameables: {
    __typename: true,
    name: true,
    '...on CardStack': {
      cards: {
        Defense: true,
      },
    },
    '...on Card': {
      Attack: true,
    },
  },
});
```

giving the following response:

```json
{
  "nameables": [
    {
      "__typename": "EffectCard",
      "name": "Hector"
    },
    {
      "__typename": "CardStack",
      "name": "Scotty",
      "cards": [
        {
          "Defense": 1950
        },
        {
          "Defense": 76566
        }
      ]
    },
    {
      "__typename": "SpecialCard",
      "name": "Itzel"
    }
  ]
}
```

# Aliases 

Zeus supports declaring aliases by using:

```graphql
const aliasedQueryExecute = await chain('query')({
  listCards: {
    __alias: {
      atak: {
        attack: [
          { cardID: ['1'] },
          {
            name: true,
            description: true,
          },
        ],
      },
    },
  },
});
```

and this is the response:

```json
{
  "listCards": [
    {
      "atak": [
        {
          "name": "Zelma",
          "description": "Central"
        }
      ]
    }
  ]
}
```

Now you can access properties in a type-safe way like this:

```javascript
aliasedQueryExecute.listCards.map((c) => c.atak);
```

# Directives

Zeus supports using directives on fields.

```typescript
import { Chain } from './zeus';

// Create a Chain client instance with the endpoint
const chain = Chain('https://faker.graphqleditor.com/a-team/olympus/graphql');

// Query the endpoint with Typescript autocomplete for arguments and response fields
const listCardsAndDraw = await chain('query')({
  drawCard: {
    name: true,
    skills: true,
    Attack: `@skip(if: true)`,
  },
});
```

remember that you need to put in the full string instead of `true`.

## Use on object field

Use directive on `drawCard`

```ts
import { Chain } from './zeus';

// Create a Chain client instance with the endpoint
const chain = Chain('https://faker.graphqleditor.com/a-team/olympus/graphql');

// Query the endpoint with Typescript autocomplete for arguments and response fields
const listCardsAndDraw = await chain('query')({
  drawCard: {
    __directives: `@skip(if:true)`,
    name: true,
    skills: true,
  },
});
```

## Use on function

```ts
import { Chain } from './zeus';

// Create a Chain client instance with the endpoint
const chain = Chain('https://faker.graphqleditor.com/a-team/olympus/graphql');

// Query the endpoint with Typescript autocomplete for arguments and response fields
const listCardsAndDraw = await chain('query')({
  drawCard: {
    name: true,
    skills: true,
    attack: [
      {
        cardId: ['2312321'],
      },
      {
        __directives: `@skip(if:true)`,
        name: true,
        skills: true,
      },
    ],
  },
});
```

## Use it with variables

```ts
import { Chain } from './zeus';

// Create a Chain client instance with the endpoint
const chain = Chain('https://faker.graphqleditor.com/a-team/olympus/graphql');
const variables = useZeusVariables({
    isDefense: 'Boolean!'
})({
    isDefense:true
});
const { $ } = variables;
// Query the endpoint with Typescript autocomplete for arguments and response fields
const listCardsAndDraw = await chain('query')({
  drawCard: {
    name: true,
    skills: true,
    Attack: `@skip(if: ${$('isDefense')})`,
  },
  {
      variables
  }
});
```

# Variables 

It's simple to perform queries with variables by using the `useZeusVariables` function. It also forces you to be type-safe.

```ts
import { Gql, $ } from './zeus';

const addCardResult = await Gql('mutation')(
  {
    addCard: [
      {
        card: $('card'),
      },
      {
        id: true,
        description: true,
        name: true,
        Attack: true,
        skills: true,
        Children: true,
        Defense: true,
        cardImage: {
          bucket: true,
          region: true,
          key: true,
        },
      },
    ],
  },
  {
    variables: {
      Attack: 2,
      Defense: 3,
      description: 'Lord of the mountains',
      name: 'Golrog',
    },
  },
);
```

## TypedDocumentNode + Apollo Client useMutation examples

The following example demonstrates usage with Apollo. Other clients should work similarly.

```tsx
import { typedGql } from './zeus/typedDocumentNode';
import { $ } from './zeus';
import { useMutation } from '@apollo/client';

const myMutation = typedGql('mutation')({
  cardById: [{ cardId: $('cardId', 'String!') }, { name: true }],
});

const Main = () => {
  const [mutate] = useMutation(myMutation);
  // data response is typed
  return (
    <div
      onClick={() => {
        // this are typesafe vars
        mutate({
          variables: {
            cardId: 'du1hn298u1eh',
          },
        });
      }}>
      Click
    </div>
  );
};
```

# Scalars

Zeus supports encoding and decoding scalars

## Decode

The decode function is called every time a scalar returns from the backend, before passing the result from `Chain` Subscription functions

```graphql
scalar JSON
scalar Datetime
type Card{
    info: JSON!
    createdAt: Datetime
}
type Query:{
    drawCard: Card!
}
```

```typescript
import { Chain } from './zeus';

// Create a Chain client instance with the endpoint
const chain = Chain('https://faker.graphqleditor.com/a-team/olympus/graphql');

// Query the endpoint with Typescript autocomplete for arguments and response fields
const data = await chain('query', {
  scalars: {
    JSON: {
      encode: (e: unknown) => JSON.stringify(e),
      decode: (e: unknown) => JSON.parse(e as string),
    },
    Datetime: {
      decode: (e: unknown) => new Date(e as string),
      encode: (e: unknown) => (e as Date).toISOString(),
    },
  },
})({
  drawCard: {
    info: true,
  },
});
```

The `data.drawCard.info` will be of type `Date` as provided by the decoder `ReturnType`

## Encode Scalars

You can also encode scalars before sending them to the backend:

```typescript
import { Chain } from './zeus';

// Create a Chain client instance with the endpoint
const chain = Chain('https://faker.graphqleditor.com/a-team/olympus/graphql');

// Query the endpoint with Typescript autocomplete for arguments and response fields
const listCardsAndDraw = await chain('query', {
  scalars: {
    JSON: {
      encode: (e: unknown) => JSON.stringify(e),
      decode: (e: unknown) => JSON.parse(e as string),
    },
    Datetime: {
      decode: (e: unknown) => new Date(e as string),
      encode: (e: unknown) => (e as Date).toISOString(),
    },
  },
})({
  drawCard: {
    info: true,
  },
});
```

Encoders require values to be encoded to the string and don't work with variables yet.

## Place decoders and encoders in one place for reuse

```typescript
import { Chain, ZeusScalars } from './zeus';

// Create a Chain client instance with the endpoint
const chain = Chain('https://faker.graphqleditor.com/a-team/olympus/graphql');
const scalars = ZeusScalars({
  JSON: {
    encode: (e: unknown) => JSON.stringify(e),
    decode: (e: unknown) => JSON.parse(e as string),
  },
  Datetime: {
    decode: (e: unknown) => new Date(e as string),
    encode: (e: unknown) => (e as Date).toISOString(),
  },
});

// Query the endpoint with Typescript autocomplete for arguments and response fields
const listCardsAndDraw = await chain('query', {
  scalars,
})({
  drawCard: {
    info: true,
  },
});
# Subscriptions

Zeus supports [GraphQL over WebSocket subscriptions](https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md) out-of-the-box and is compatible with many popular GraphQL servers.

Two implementations are supported:

* **graphql-ws**: the modern WebSocket-based transport, implemented by [the graphql-ws package](https://www.npmjs.com/package/graphql-ws). It is also the standard [used by Apollo](https://www.apollographql.com/docs/react/data/subscriptions/#choosing-a-subscription-library)
* **legacy** (default): a transport based on raw WebSockets

## Generating the client

To use [graphql-ws](https://www.npmjs.com/package/graphql-ws) as your subscription transport you'll need to do the following:

```
# Generate the client
zeus schema.gql ./ --subscriptions graphql-ws
# Add graphql-ws to your project's dependencies
npm install graphql-ws
```

If you want to use the **legacy** method, use the `--subscriptions legacy` flag instead. You may need to install [ws](https://www.npmjs.com/package/ws) depending on your setup.

No matter what implementation you chose, the usage remains the same:

```typescript
// Create a new Subscription with some authentication headers
const wsChain = Subscription('wss://localhost:4000/graphql', {
  get headers() {
    return { Authorization: `Bearer ${getToken()}` };
  },
});

// Subscribe to new messages
wsChain('subscription')({
  message: {
    body: true,
  },
}).on(({ message }) => {
  console.log(message.body);
});
```

If you need to unsubscribe from a subscription (e.g. you are developing a Single Page App), you can do it as follows:

```typescript
// Subscribe to new messages
const onMessage = wsChain('subscription')({
  message: {
    body: true,
  },
});
onMessage.on(({ message }) => {
  console.log(message.body);
});

// Close the underlying connection
onMessage.ws.close();
```

While you can use `wsChain('query')` or `wsChain('mutation')`, [Apollo strongly discourages this practice.](https://www.apollographql.com/docs/react/data/subscriptions/#3-split-communication-by-operation-recommended)

---
_Source: https://npm.io/package/graphql-zeus · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
