DEV Community

Cover image for Boost Your React Development with GraphQL and Codegen
Rijen Manandhar
Rijen Manandhar

Posted on

Boost Your React Development with GraphQL and Codegen

In modern web development, GraphQL has become a popular choice for API interactions, especially when working with complex and flexible data needs. Its ability to fetch exactly what you want — no more, no less — makes it a perfect match for the highly modular and component-driven architecture of React.

But while GraphQL provides powerful flexibility, it can also introduce the risk of errors, especially when your queries are not in sync with the schema. That’s where GraphQL Code Generator (or Codegen) comes in. It automatically generates TypeScript typings, hooks, and components for your queries based on your schema, improving type safety and speeding up development.
In this article, we'll go over how to set up GraphQL in a React project with Codegen to supercharge your workflow.

Why Use GraphQL with Codegen?

  • Before diving into the implementation, let's quickly understand why GraphQL with Codegen is such a powerful combination:
  • Type Safety: GraphQL Codegen automatically generates TypeScript types based on your GraphQL schema, eliminating manual type definition and reducing bugs caused by inconsistent types.
  • Auto-Generated Hooks: Codegen can create React hooks for your GraphQL queries, making it seamless to integrate queries and mutations directly into your components.
  • Productivity Boost: With auto-generated types, components, and hooks, you’ll spend less time writing boilerplate code and more time focusing on building features.
  • Error Reduction: Codegen helps eliminate runtime errors by ensuring your queries are always in sync with the API schema, allowing you to catch issues during compile time.

Now, let's get hands-on.

Getting Started

We’ll walk through setting up a React app with Apollo Client, GraphQL, and GraphQL Code Generator to automatically generate hooks and types.

Step 1: Setting Up the Project

First, create a new React app if you don’t have one yet. We are going to use vite in this example:

yarn create vite graphql-codegen-app
Enter fullscreen mode Exit fullscreen mode

Next, install the required dependencies for GraphQL and Apollo Client:

yarn add @apollo/client graphql
Enter fullscreen mode Exit fullscreen mode

Here @apollo/client package allows to create GraphQL client that interacts with your schema, including fetching data, caching, and managing subscriptions and graphql package allows to define your GraphQL schema, including types, queries, mutations, and subscriptions.
Now, install the GraphQL Code Generator and the necessary plugins:

yarn add --dev @graphql-codegen/cli @graphql-codegen/client-preset
Enter fullscreen mode Exit fullscreen mode

We are installing these packages as a dev dependency. Here,
@graphql-codegen/cli is the command-line interface (CLI) for GraphQL Code Generator and @graphql-codegen/client-preset is a preset for GraphQL Code Generator, specifically designed for generating client-side code such as TypeScript types.

Step 2: Configuring Apollo Client

To use apollo client within our application we need to configure apollo client and wrap it around the app in main.tsx file.

import React from 'react'
import ReactDOM from 'react-dom/client'
import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client"

import App from './App.tsx'

import './index.css'

//You can configure in separate file
const client = new ApolloClient({
  uri: 'https://graphql-pokeapi.graphcdn.app/graphql', // Replace with your GraphQL API endpoint
  cache: new InMemoryCache(),
});

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  </React.StrictMode>,
)
Enter fullscreen mode Exit fullscreen mode

Step 3: Setting Up Codegen

To configure GraphQL Codegen, create a file called codegen.yml in the root of your project:

schema: 'https://graphql-pokeapi.graphcdn.app/graphql'  # Replace with your GraphQL API endpoint
documents: ['src/**/*.{ts,tsx}']
generates:
  ./src/__generated__/:
    preset: 'client'
    plugin: []
    presetConfig: 
        gqlTagName: 'gql'
ignoreNoDocuments: true,
Enter fullscreen mode Exit fullscreen mode
  1. schema: This specifies the URL of the GraphQL API endpoint that the generator will use to fetch the schema. In this case, it's set to https://graphql-pokeapi.graphcdn.app/graphql, which is a public GraphQL API for Pokemon data.
  2. documents: This specifies the location of the GraphQL query documents (i.e., .ts or .tsx files) that the generator will use to generate code. The src/*/.{ts,tsx} pattern means the generator will look for files with .ts or .tsx extensions in the src directory and all its subdirectories.
  3. generates: This section specifies the output configuration for the generated code.
  4. ./src/generated/: This is the output directory where the generated code will be written.
  • preset: 'client': This specifies the preset configuration for the generator. In this case, it's set to client, which means the generator will produce code optimized for a client-side application.
  • plugin: []: This is an empty array, which means no additional plugins are being used to customize the generation process.
  • presetConfig: This section specifies additional configuration options for the preset.
  • gqlTagName: 'gql': This specifies the tag name to use for GraphQL tagged template literals. In this case, it's set to gql, which means the generated code will use gql as the tag name for GraphQL queries. ignoreNoDocuments: This flag is set to true, which means the generator will ignore files that don't contain any GraphQL documents (i.e., queries or mutations). This can be useful if you have files in your src directory that don't contain GraphQL code.

Step 4: Add the codegen script

Add a codegen script into your package.json file:

"generate": "graphql-codegen"
Enter fullscreen mode Exit fullscreen mode

Then run the script in your terminal

yarn generate
Enter fullscreen mode Exit fullscreen mode

This will generate a folder named __generated__ inside src folder which includes:

  • fragment-masking: This file contains generated TypeScript types and utilities for fragment masking. Fragment masking is a technique to selectively retrieve only the necessary fields from a GraphQL fragment, reducing the amount of data transferred between the client and server.
  • gql: This file contains the GraphQL schema definitions, such as queries, mutations, and subscriptions, in a string format. The .gql files are used as input for the GraphQL Code Generator to generate TypeScript types and other artifacts.
  • graphql: This file contains generated GraphQL-related code, such as resolvers, schema definitions, or other utility functions. The graphql files might include generated code for Apollo Client, GraphQL hooks, or other GraphQL-related libraries.

Step 5: Writing a GraphQL Query

Create a graphql/queries folder inside src and add a sample GraphQL query. In this example, let’s query a list of pokemons:

import { gql } from "../__generated__";

export const GET_POKEMON = gql(`
query pokemons($limit: Int, $offset: Int) {
  pokemons(limit: $limit, offset: $offset) {
    count
    next
    previous
    status
    message
    results {
      url
      name
      image
    }
  }
}
`);
Enter fullscreen mode Exit fullscreen mode

Then run yarn generate once again. This will generate all the types for your query inside the graphql folder.

Step 6: Integrate the query inside the component

Once we have generate the type, we can make use of useQuery hook from @apollo/client

import { useQuery } from '@apollo/client'
import { GET_POKEMON } from './graphql/query'

function App() {
  const { data, loading } = useQuery(GET_POKEMON);

  if (loading) {
    return <p>Loading...</p>
  }
  return (
    <>
      <h1>Pokemon List</h1>
      {
        data?.pokemons?.results?.length ?
          data?.pokemons?.results?.map(pokemon => (
            <p key={pokemon?.name}>
              {pokemon?.name}
            </p>
          )) : null
      }
    </>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Conclusion

By combining GraphQL and Codegen, you can dramatically improve the type safety, speed, and productivity of your React development process. This setup ensures that your code is always in sync with your GraphQL schema, reduces the chances of runtime errors, and saves you from writing repetitive boilerplate code.
Whether you're working on large-scale applications or small projects, this workflow will streamline your development and allow you to focus on building features instead of worrying about manual type management.

Top comments (0)