# GraphQL Codegen with React Query

In this guide, we will learn how to use the GraphQL Code Generator client preset with React Query to generate type-safe operations and wire it up to a GraphQL server that supports the GraphQL over HTTP protocol.

## Prerequisites

For this guide, we assume that you are querying your GraphQL server from within a Browser environment. So you already have your Vite, Next.js, Node.js or any other vanilla project with TypeScript setup.

We are going to use the public [Star Wars GraphQL API](https://swapi-graphql.netlify.app/) as our GraphQL endpoint.

## Setting up GraphQL Code Generator

The GraphQL Code Generator client preset is the preferred and built-in way to generate type-safe operations for any GraphQL client library and also vanilla JavaScript.

To get started, install the following dependencies:

- **`@graphql-codegen/cli`**: Codegen CLI for running code generation
- **`@parcel/watcher`**: Enable watch mode for the codegen CLI
- **`@graphql-codegen/schema-ast`**: Plugin for generating the schema file from the GraphQL API endpoint (optional if you already have a schema file)
- **`@0no-co/graphqlsp`**: TypeScript language server plugin for GraphQL auto-complete (optional)

Feel free to omit the optional dependencies if you don’t need them.

### npm
```bash
npm install --save-dev @graphql-codegen/cli @parcel/watcher
npm install --save-dev @graphql-codegen/schema-ast
npm install --save-dev @0no-co/graphqlsp
```

### pnpm
```bash
pnpm add --save-dev @graphql-codegen/cli @parcel/watcher
pnpm add --save-dev @graphql-codegen/schema-ast
pnpm add --save-dev @0no-co/graphqlsp
```

### yarn
```bash
yarn add --dev @graphql-codegen/cli @parcel/watcher
yarn add --dev @graphql-codegen/schema-ast
yarn add --dev @0no-co/graphqlsp
```

### bun
```bash
bun add --dev @graphql-codegen/cli @parcel/watcher
bun add --dev @graphql-codegen/schema-ast
bun add --dev @0no-co/graphqlsp
```

After that, we can create a `codegen.ts` file in the root of our project with the following contents:

### GraphQL Codegen Configuration
```typescript
import type { CodegenConfig } from '@graphql-codegen/cli'

const config: CodegenConfig = {
  schema: 'https://graphql.org/graphql/',
  documents: ['src/**/*.{ts,tsx}'],
  ignoreNoDocuments: true,
  generates: {
    './src/graphql/': {
      preset: 'client',
      config: {
        documentMode: 'string'
      }
    },
    './schema.graphql': {
      plugins: ['schema-ast'],
      config: {
        includeDirectives: true
      }
    }
  }
}

export default config
```

Next, we adjust our `tsconfig.json` to load `@0no-co/graphqlsp`.

### tsconfig.json
```json
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": "./schema.graphql"
      }
    ]
  }
}
```

Finally, we also need to prompt Visual Studio Code to use the local TypeScript version by creating a `.vscode/settings.json` file with the following contents:

### .vscode/settings.json
```json
{
  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.enablePromptUseWorkspaceTsdk": true
}
```

## Running the Code Generator

Now we can run the following command to generate the `schema.graphql` file and the GraphQL Code Generator client code. **Note:** We are not yet writing GraphQL operations in our codebase, we just generate the client boilerplate code.

### Run GraphQL Code Generator
```bash
npx graphql-codegen --config codegen.ts
```

After running the command, you should see a new `schema.graphql` file in the root of your project and a new folder `src/graphql` with the generated client code.

You almost never need to touch the files within `src/graphql` as they are generated and overwritten by GraphQL Code generator.

We will now use the generated client code to write our type-safe GraphQL operations.

## Writing GraphQL Operations

Let’s start GraphQL Code Generator in watch mode to generate the client code whenever we write our code.

### Run GraphQL Code Generator in watch mode
```bash
npx graphql-codegen --config codegen.ts --watch
```

Next within any file in our project `src` folder, we will import the `graphql` function from within `src/graphql`.

### src/index.ts
```typescript
import { graphql } from './graphql'
```

This function allows us to define a GraphQL operation.

Thanks to the TypeScript GraphQL LSP plugin, we get auto-complete for our GraphQL operations while writing them.

With that, we will write a simple query operation to get the total count of people in the Star Wars universe.

### src/index.ts
```typescript
import { graphql } from './graphql'

const PeopleCountQuery = graphql(`
  query PeopleCount {
    allPeople {
      totalCount
    }
  }
`)
```

As we now save the file in our editor, the GraphQL Code Generator will generate the corresponding types, and as you hover over the `PeopleCountQuery` variable, you will see the following:

`TypedDocumentString` is a container type that holds the query operation string and also the TypeScript type for that operation's response.

We can now leverage this to build a type-safe function that executes the GraphQL operation against our GraphQL server.

## Type-Safe GraphQL Operation Execution

We can build a simple wrapper around `fetch` that takes a `TypedDocumentString` parameter and returns a typed response.

### src/graphql/execute.ts
```typescript
import type { TypedDocumentString } from './graphql'

export async function execute<TResult, TVariables>(
  query: TypedDocumentString<TResult, TVariables>,
  ...[variables]: TVariables extends Record<string, never> ? [] : [TVariables]
) {
  const response = await fetch('https://graphql.org/graphql/', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Accept: 'application/graphql-response+json'
    },
    body: JSON.stringify({
      query,
      variables
    })
  })

if (!response.ok) {
    throw new Error('Network response was not ok')
  }

return response.json() as TResult
}
```

We can now use this function to execute our `PeopleCountQuery` operation.

### src/index.ts
```typescript
import { graphql } from './graphql'
import { execute } from './graphql/execute'

const PeopleCountQuery = graphql(`
  query PeopleCount {
    allPeople {
      totalCount
    }
  }
`)

execute(PeopleCountQuery).then(data => {
  console.log(data)
})
```

When we now hover over the `data` parameter in the `then` callback, we can see that the response is fully typed.

## Executing Query Operations with React Query

We can now leverage the `execute` function to execute our GraphQL operations with React Query.

### Example usage of executing a Query Operation with React Query
```typescript
import { useQuery } from '@tanstack/react-query'
import { graphql } from './graphql'
import { execute } from './graphql/execute'

const PeopleCountQuery = graphql(`
  query PeopleCount {
    allPeople {
      totalCount
    }
  }
`)

function App() {
  const { data } = useQuery({
    queryKey: ['films'],
    queryFn: () => execute(PeopleCountQuery)
  })

return <div>There are {data?.allPeople.totalCount} people</div>
}
```

## Conclusion

In this article, we learned how to use the GraphQL Code Generator preset with React Query.

If you want to learn more about GraphQL Code Generator, check out the [client preset documentation](/content/graphql/codegen/plugins/presets/preset-client/index.html). E.g. you want to reduce bundle size by using the [client preset babel plugin](/content/graphql/codegen/plugins/presets/preset-client#reducing-bundle-size/index.html) or enable [persisted documents](/content/graphql/codegen/plugins/presets/preset-client#persisted-documents/index.html) in production for security and performance reasons.
