Skip to content

Instantly share code, notes, and snippets.

@bignimbus
Last active March 21, 2025 18:30
Show Gist options
  • Save bignimbus/457f9ac42f29d0bb6c4eb742ad03c264 to your computer and use it in GitHub Desktop.
Save bignimbus/457f9ac42f29d0bb6c4eb742ad03c264 to your computer and use it in GitHub Desktop.
Migrating from `apollo` CLI codegen to GraphQL Code Generator

Credit: Jerel Miller (June 2024)

I've been experimenting with the two tools to compare codegen outputs and I was able to get a config for codegen that gets close to the apollo CLI's output. Unfortunately its not 100% 1:1. The biggest difference between the two is the name of the file you import from and unfortunately graphql-codegen isn't configurable in a way that allows you to name the files how the apollo codegen tool does. First the config, then I'll talk about it:This requires 1 preset and 2 plugins:

const config: CodegenConfig = {
  generates: {
    './src/types/globalTypes.ts': {
      schema: [
        /* your schema config */
      ],
      documents: ['src/**/*.{ts,tsx}'],
      plugins: ['typescript'],
      config: {
        avoidOptionals: {
          field: true,
          inputValue: false,
          object: false,
          defaultValue: false,
        },
        nonOptionalTypename: true,
        namingConvention: {
          typeNames: 'keep',
          enumValues: 'change-case-all#upperCase',
        },
      },
    },
    './src/': {
      schema: [
        /* your schema config */
      ],
      documents: ['src/**/*.{ts,tsx}'],
      preset: 'near-operation-file',
      plugins: ['typescript-operations'],
      config: {
        omitOperationSuffix: true,
        nonOptionalTypename: true,
        avoidOptionals: {
          field: true,
          inputValue: false,
          object: false,
          defaultValue: false,
        },
      },
      presetConfig: {
        baseTypesPath: 'types/globalTypes.ts',
        folder: '__generated__',
        extension: '.ts',
      },
    },
  }
}

There are a couple pieces. That first globalTypes file mimics the global file generated by apollo codegen. This will be used by the near operation file preset in case it needs to pull in types such as enums.The 2nd bit of configuration helps mimic the TS type output that apollo codegen does, such as ensuring typename is non-optional and making sure nullable types use null and not optional fields.There are a few differences on the global types file between the two, but none that should affect you:

  • apollo codegen only writes shared enums to this file
  • graphql codegen writes types for your entire schema

The configuration above ensures the enum keys are named the same, so really the difference here is that the graphql codegen global types file will have more in it than the apollo codegen does.The other big difference which unfortunately I don't think you'll be able to get around is the file name generated by graphql-codegen. It looks like apollo's codegen will write a file per operation/fragment named the same as the operation/fragment. gql codegen on the other hand names the file after the source file where it found the operation. If you have multiple operations/fragments in a single file, those will get written to the same file in gql codegen with multiple exports. So it looks like you'll likely need to do some updates to the codebase on the filename from which you import these types.The other difference I spotted between the two generated files is the set of types it exports. apollo codegen will output subtypes for any nested fields as their own imports. I believe it names it something like etc. gql codegen inlines the object types here. I don't know if you import those subtypes at all, but this would also require some changes if you need to access them. The top-level import types though are the same between the two.

We've gotten some feedback from teams who have hundreds and hundreds of graphql type files, so changing all the file names has been a significant effort for them. Teams that use nested fields very heavily are particularly affected.

Jerel put together a branch using our spotify showcase that highlights the difference between the two in-depth. You can compare all output here: https://github.com/apollographql/spotify-showcase/compare/6581af494946b4e9ff97f7643fbb6eaced3764b8...compare-codegen-outputIf you want to see how each tool output types, check out these two commits:

Beyond that, it's tough to speculate on what an individual codebase's needs are. GraphQL Code Generator is a marvelous tool but it wasn't necessarily designed for 1:1 compatibility with Apollo - it's not maintained by us. We are extremely appreciative, though, that this tool is available for the community.

Ultimately, you should view moving to GraphQL Code Generator as bumping a dependency by a major version. It's a backwards-incompatible change but ultimately necessary to go through with for the long-term maintainability of your app code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment