From 916d0236f6952c8ea7d88294d79be27986a1ae97 Mon Sep 17 00:00:00 2001 From: Igor Kusakov Date: Wed, 11 Mar 2026 09:01:30 -0400 Subject: [PATCH] Documentation for migrating from Apollo Tooling to GraphQL Codegen (#10612) * docs * fixed docs * added more docs * better comments * Run prettier --------- Co-authored-by: Igor Kusakov Co-authored-by: Eddy Nguyen Co-authored-by: Eddy Nguyen --- website/src/pages/docs/migration/_meta.ts | 1 + .../pages/docs/migration/apollo-tooling.mdx | 303 ++++++++++++++++++ 2 files changed, 304 insertions(+) create mode 100644 website/src/pages/docs/migration/apollo-tooling.mdx diff --git a/website/src/pages/docs/migration/_meta.ts b/website/src/pages/docs/migration/_meta.ts index cb478134ae5..bac9bd6ce39 100644 --- a/website/src/pages/docs/migration/_meta.ts +++ b/website/src/pages/docs/migration/_meta.ts @@ -4,4 +4,5 @@ export default { 'from-0-13': 'v0.13 -> v0.17', 'from-4-0': 'v4.0 -> v5.0', 'operations-and-client-preset-from-5-0': 'typescript-operations and client-preset v5.0 -> v6.0', + 'apollo-tooling': 'Apollo Tooling -> GraphQL Code Generator', }; diff --git a/website/src/pages/docs/migration/apollo-tooling.mdx b/website/src/pages/docs/migration/apollo-tooling.mdx new file mode 100644 index 00000000000..d5585904260 --- /dev/null +++ b/website/src/pages/docs/migration/apollo-tooling.mdx @@ -0,0 +1,303 @@ +--- +description: Migrating from Apollo Tooling (apollo client:codegen) to GraphQL Code Generator. What has changed? How to migrate? What configuration options replace Apollo Tooling's behaviour? +--- + +import { Callout, Tabs } from '@theguild/components' + +# Migrating from Apollo Tooling to GraphQL Code Generator + +[Apollo Tooling](https://github.com/apollographql/apollo-tooling) (the `apollo` CLI, specifically `apollo client:codegen`) is a code generation tool that generates TypeScript types from GraphQL operations for use with Apollo Client. + +This guide explains how to replace it with [GraphQL Code Generator](https://the-guild.dev/graphql/codegen), which is actively maintained, more flexible, and supports a broader range of use cases. + + + This setup is available in the next major version of `graphql-code-generator` and `graphql-code-generator-community`. + + +## Installation + +Remove Apollo Tooling and install GraphQL Code Generator: + + + +```sh npm2yarn +npm uninstall apollo +``` + + + +```sh npm2yarn +npm i -D @graphql-codegen/cli @graphql-codegen/typescript-operations @graphql-codegen/near-operation-file-preset +``` + + + +### Required packages + +| Package | Description | +| --------------------------------------------- | ------------------------------------------------------------------ | +| `@graphql-codegen/cli` | Core CLI that runs the code generator | +| `@graphql-codegen/typescript-operations` | Plugin that generates TypeScript types for GraphQL operations | +| `@graphql-codegen/near-operation-file-preset` | Preset that places generated files next to their source operations | + +```json filename="package.json" +{ + "devDependencies": { + ... + "@graphql-codegen/cli": "...", + "@graphql-codegen/typescript-operations": "...", + "@graphql-codegen/near-operation-file-preset": "..." + ... + } +} +``` + +## Configuration + +Apollo Tooling is configured via `apollo.config.js` (or `apollo.config.ts`) and invoked with `apollo client:codegen`. GraphQL Code Generator uses a `codegen.ts` file and is invoked with `graphql-codegen`. + + + +```js filename="apollo.config.js" +module.exports = { + client: { + service: { + name: 'my-service', + localSchemaFile: './schema.graphql', + }, + includes: ['./src/**/*.tsx', './src/**/*.ts'], + }, +} +``` + +```sh +apollo client:codegen --target=typescript --outputFlat src/__generated__/types.ts +``` + + + + +```ts filename="codegen.ts" +import type { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { +schema: './schema.graphql', +documents: ['./src/**/*.{ts,tsx}', '!./src/**/__generated__/**'], +generates: { +'./src/': { +preset: 'near-operation-file', +presetConfig: { +extension: '.ts', +folder: '**generated**', +filePerOperation: true, +inGeneratesOnly: true, +}, +plugins: ['typescript-operations'], +}, +}, +} + +export default config +``` + +```sh +graphql-codegen +``` + + + + +Add a script to your `package.json` to run the code generator: + +```json filename="package.json" +{ + "scripts": { + "codegen": "graphql-codegen" + } +} +``` + +## Per-file generation with `near-operation-file` + +Apollo Tooling's default behaviour is to generate one TypeScript file per graphql operation, placed in a `__generated__` folder next to the source. +For example, given `src/Component.ts` containing a query `GetUser`, Apollo Tooling produces `src/__generated__/GetUser.ts`. + +GraphQL Code Generator replicates this with the [`near-operation-file` preset](https://the-guild.dev/graphql/codegen/plugins/presets/near-operation-file-preset). + +```ts filename="codegen.ts" +import type { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: './schema.graphql', + documents: ['./src/**/*.{ts,tsx}', '!./src/**/__generated__/**'], + generates: { + './src/': { + preset: 'near-operation-file', + presetConfig: { + extension: '.ts', // Extension for generated files + folder: '__generated__', // Generated files go into __generated__/ subfolder + filePerOperation: true, // Generate type files per-operation (not per-component) + inGeneratesOnly: true // Only generate files defined in `generates` scan paths (don't generate for all `documents`) + }, + plugins: ['typescript-operations'] + } + } +} + +export default config +``` + +With this configuration, `src/Component.ts` → `src/__generated__/Component.ts`, matching Apollo Tooling's output structure exactly. + +## Type naming conventions + +Apollo Tooling generates type names using **only field names**, omitting the GraphQL object type name: + +```ts +// Apollo Tooling output +export type GetUserQuery_user = { ... }; +export type GetUserQuery_user_address = { ... }; +``` + +To achieve similar naming with GraphQL Codegen use the `extractAllFieldsToTypesCompact: true` configuration option: + +```ts filename="codegen.ts" +const config: CodegenConfig = { + schema: './schema.graphql', + documents: ['./src/**/*.{ts,tsx}', '!./src/**/__generated__/**'], + generates: { + './src/': { + preset: 'near-operation-file', + presetConfig: { + extension: '.ts', + folder: '__generated__', + filePerOperation: true, + inGeneratesOnly: true + }, + plugins: ['typescript-operations'], + config: { + extractAllFieldsToTypesCompact: true + } + } + } +} +``` + +## Enum types + +Apollo Tooling generates enums as native TypeScript `enum` declarations and references them directly by name (without any namespace prefix): + +```ts +// Apollo Tooling output +export enum UserManagerRoleType { + ROLE_TYPE_1 = 'ROLE_TYPE_1', + ROLE_TYPE_2 = 'ROLE_TYPE_2', + ROLE_TYPE_3 = 'ROLE_TYPE_3' +} + +export type GetUserQuery_user_manager = { + roleType: UserManagerRoleType +} +``` + +GraphQL Code Generator generates string literal union types by default. To produce native `enum` declarations matching Apollo Tooling's output, set `enumType: 'native'`: + +```ts filename="codegen.ts" +const config: CodegenConfig = { + schema: './schema.graphql', + documents: ['./src/**/*.{ts,tsx}', '!./src/**/__generated__/**'], + generates: { + './src/': { + preset: 'near-operation-file', + presetConfig: { + extension: '.ts', + folder: '__generated__', + filePerOperation: true, + inGeneratesOnly: true + }, + plugins: ['typescript-operations'], + config: { + extractAllFieldsToTypesCompact: true, + enumType: 'native' + } + } + } +} +``` + + + Native TypeScript `enum` declarations incur a runtime cost (they compile to JavaScript objects). If you only need + type-level checking, consider using the default `string-literal` enum type instead: + +```ts +type UserManagerRoleType = 'ROLE_TYPE_1' | 'ROLE_TYPE_2' | 'ROLE_TYPE_3' +``` + +See the [typescript-operations configuration reference](https://the-guild.dev/graphql/codegen/plugins/typescript/typescript-operations#enumtype) for all available enum type options. + + + +## Recommended configuration + +Below is a configuration that produces output closely matching Apollo Tooling's behaviour, including per-file generation, enum output, and type naming: + +```ts filename="codegen.ts" +import type { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: './schema.graphql', + documents: ['./src/**/*.{ts,tsx}', '!./src/**/__generated__/**'], + generates: { + './src/': { + preset: 'near-operation-file', + presetConfig: { + extension: '.ts', + folder: '__generated__', + // Generate type files per-operation (not per-component) + filePerOperation: true, + // Only generate files defined in `generates` scan paths (don't generate for all `documents`) + inGeneratesOnly: true + }, + plugins: ['typescript-operations'], + config: { + // Keep original naming as-is (no camelCase conversion) + namingConvention: 'keep', + // Extract nested field types to named types (matches Apollo Tooling naming) + extractAllFieldsToTypesCompact: true, + // Print each field on its own line for readability + printFieldsOnNewLines: true, + // Use native TypeScript enums (matches Apollo Tooling enum output) + enumType: 'native', + // Always include __typename in result types + nonOptionalTypename: true, + // Don't add __typename to root query/mutation/subscription types + skipTypeNameForRoot: true, + // Don't add 'Query'/'Mutation'/'Subscription' suffixes to operation result types + omitOperationSuffix: true, + // Don't add 'Fragment' suffix to fragment result types + fragmentSuffix: '' + } + } + } +} + +export default config +``` + +## Manual changes + +The setup above closely mimics Apollo Tooling but isn’t an exact match. The following items may require manual fixes: + +1. Nested field types naming. In very rare cases, the names generated by GraphQL Codegen don’t match Apollo Tooling’s. Update these cases manually. + +2. Enum file location. Occasionally, GraphQL Codegen places enums in a different file. If an enum is missing, check nearby generated files and adjust your imports accordingly. + +3. Occasional mismatch between `Type | null` and `Type | null | undefined`. + +4. Occasional `is possibly null` and `has any type` typecheck bugs. + +## Further reading + +- [GraphQL Code Generator configuration reference](https://the-guild.dev/graphql/codegen/docs/config-reference/codegen-config) +- [typescript-operations plugin documentation](https://the-guild.dev/graphql/codegen/plugins/typescript/typescript-operations) +- [near-operation-file preset documentation](https://the-guild.dev/graphql/codegen/plugins/presets/near-operation-file-preset)