Labs ICT
Pro Login

GraphQL Code Generation

GraphQL Code Generation

GraphQL Code Generator (codegen) automatically generates TypeScript types and helper functions from your GraphQL schema and queries. It eliminates manual type definitions and reduces errors.

Why Use Codegen?

Without codegen, you'd manually define TypeScript types that match your schema. This is error-prone and tedious. Codegen does this automatically.

// Before codegen: Manual types (can drift from schema)
interface User {
  id: string;
  name: string;
  email: string;
}

// After codegen: Auto-generated types (always in sync)
// Generated automatically from schema
export type User = {
  __typename?: 'User';
  id: string;
  name: string;
  email: string;
};

Codegen ensures your TypeScript types always match your GraphQL schema.

Setting Up Codegen

Install the codegen packages and create a configuration file:

// Install dependencies
npm install -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typescript-react-apollo

// codegen.yml
schema: "http://localhost:4000/graphql"
documents: "src/**/*.graphql"
generates:
  src/generated/graphql.ts:
    plugins:
      - typescript
      - typescript-operations
      - typescript-react-apollo
    config:
      withHooks: true

The configuration tells codegen where to find your schema and queries.

Writing Query Files

Write your queries in .graphql files instead of inline strings:

// src/queries/users.graphql
query GetUsers {
  users {
    id
    name
    email
  }
}

query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
    email
    posts {
      title
    }
  }
}

mutation CreateUser($input: CreateUserInput!) {
  createUser(input: $input) {
    id
    name
  }
}

These files are what codegen uses to generate types.

Using Generated Types

After running codegen, you get fully typed hooks and operations:

// Run codegen
npx graphql-codegen

// Use generated hooks in your components
import { useGetUsersQuery, useCreateUserMutation } from './generated/graphql';

function UserList() {
  // Fully typed - autocomplete works, errors are caught at compile time
  const { data, loading, error } = useGetUsersQuery();

  return (
    <ul>
      {data?.users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

function CreateUser() {
  const [createUser] = useCreateUserMutation();

  const handleClick = () => {
    createUser({
      variables: {
        input: {
          name: 'Charlie', // TypeScript checks this matches CreateUserInput
          email: 'charlie@example.com',
        },
      },
    });
  };
}

You get full TypeScript support with autocomplete and type checking.