Episode 23 builds end-to-end type safety with GraphQL Code Generator: installing and configuring codegen.yml, generating TypeScript types from the schema, generating typed React hooks, type-safe resolvers and context, and integrating watch mode and pre-commit hooks.

TypeScript makes JavaScript safer, but without integration, the types in GraphQL and TypeScript can drift apart — the schema says one thing, the code says another. Episode 23 unifies the two with GraphQL Code Generator.
Codegen reads your schema and queries, then generates TypeScript types that guarantee: if the schema changes, wrong-typed code fails at compile time immediately. We'll cover installation, configuration, server and client type generation, and workflow integration.
GraphQL Code Generator is a tool that turns GraphQL schemas into code. Its input: a schema (SDL, introspection, or endpoint) and documents (queries, mutations, fragments). Its output: TypeScript types, React hooks, and much more via plugins.
npm install -D @graphql-codegen/cli @graphql-codegen/typescriptThe main benefit is one word: type safety. If the schema adds non-null or removes a field, stale client code and resolvers fail compilation immediately — not in production.
Create codegen.yml:
schema: http://localhost:4000
documents: "src/**/*.graphql"
generates:
src/generated/types.ts:
plugins:
- typescript
- typescript-operationsRun it:
npx graphql-codegenThe command npx graphql-codegen produces a types.ts file containing all the types from the schema and operations. After this, enable watch mode during development.
The typescript plugin generates a type for every GraphQL type. For example, the schema:
type User {
id: ID!
username: String!
posts: [Post!]!
}generates:
export type User = {
__typename?: "User";
id: Scalars["ID"]["output"];
username: Scalars["String"]["output"];
posts: Array<Post>;
};All object, input, and enum types are generated automatically. Schema changes are reflected immediately — no more manual mismatches.
For the server side, the typescript-resolvers plugin generates typed resolver signatures, complete with context:
generates:
src/generated/resolvers.ts:
plugins:
- typescript
- typescript-resolvers
config:
contextType: ../context#GraphQLContextimport { Resolvers } from "./generated/resolvers";
export const resolvers: Resolvers = {
Query: {
user: (_, args, ctx) => ctx.userRepo.findById(args.id),
},
};If a resolver returns a shape that doesn't match the schema, TypeScript warns immediately. The contextType hooks into your GraphQL context so ctx is typed too.
The typescript-react-apollo plugin generates a typed useQuery and useMutation hook for every operation:
npm install -D @graphql-codegen/typescript-react-apolloschema: http://localhost:4000
documents: "src/**/*.graphql"
generates:
src/generated/hooks.tsx:
plugins:
- typescript
- typescript-operations
- typescript-react-apolloThen in a component:
import { useGetUserQuery } from "../generated/hooks";
function Profile({ userId }: { userId: string }) {
const { data, loading } = useGetUserQuery({
variables: { id: userId },
});
return <p>{data?.user.username}</p>;
}These hooks guarantee the variables and query data match the schema. Operations using wrongly-typed variables fail at compile time — an advantage that's impossible without codegen.
To keep types always in sync, integrate codegen into the workflow:
{
"scripts": {
"codegen": "graphql-codegen",
"codegen:watch": "graphql-codegen --watch"
}
}Run npm run codegen:watch during development so types update automatically whenever a file changes. In production, run codegen before typecheck in CI, and add it to a pre-commit hook (for example with Husky) so stale-typed code never gets committed:
npx husky-init
echo "npm run codegen && git add src/generated" > .husky/pre-commitTo make sure code doesn't lag too far behind the schema, run a schema check before merging (episode 32) and get in the habit of regenerating types whenever the schema changes. The combination of codegen, schema linting, and CI makes type safety a culture, not just a tool.
Key takeaways:
typescript plugin generates schema types; typescript-resolvers types resolvers with context.typescript-react-apollo plugin generates typed query and mutation hooks.codegen.yml defines the schema, documents, and per-plugin output.In the next episode, episode 24, you'll learn about monitoring, logging, and observability — structured logging strategies with Pino, setting up Apollo Studio for query analytics, OpenTelemetry integration for distributed tracing, Prometheus and Grafana metrics, and health checks. Your API will be fully watchable in production!