Skip to main content
The API Codegen Preset enables automatic TypeScript type generation for your GraphQL operations using graphql-codegen. It parses queries tagged with #graphql and generates type-safe interfaces for your Shopify API clients.

Installation

npm install --save-dev @shopify/api-codegen-preset

Quick Start

1

Install the preset

npm install --save-dev @shopify/api-codegen-preset
2

Create configuration file

Create a .graphqlrc.ts file in your project root:
import {ApiType, shopifyApiProject} from '@shopify/api-codegen-preset';

export default {
  schema: 'https://shopify.dev/admin-graphql-direct-proxy',
  documents: ['**/*.{js,ts,jsx,tsx}', '!node_modules'],
  projects: {
    default: shopifyApiProject({
      apiType: ApiType.Admin,
      apiVersion: '2025-01',
      outputDir: './types',
    }),
  },
};
3

Add npm script

Add to your package.json:
{
  "scripts": {
    "graphql-codegen": "graphql-codegen"
  }
}
4

Tag your queries

const {data} = await client.request(
  `#graphql
  query GetProducts($first: Int!) {
    products(first: $first) {
      edges {
        node {
          id
          title
        }
      }
    }
  }`,
  {variables: {first: 10}}
);
5

Generate types

npm run graphql-codegen

Configuration Options

The preset provides three levels of configuration: One-stop configuration for a complete codegen project:
apiType
ApiType
required
The Shopify API to use: ApiType.Admin, ApiType.Storefront, or ApiType.Customer
apiVersion
string
API version to use (e.g., '2025-01'). Defaults to oldest stable version
outputDir
string
default:"'.'"
Directory for generated type files
documents
string[]
default:"['**/*.{ts,tsx}']"
Glob patterns for files to parse
module
string
Override the module whose types will be augmented
declarations
boolean
default:"true"
Generate .d.ts files (true) or .ts files (false)
enumsAsConst
boolean
default:"false"
Generate enums as const assertions instead of TypeScript enums
apiKey
string
App’s API key (required for Customer Account API)
// .graphqlrc.ts
import {shopifyApiProject, ApiType} from '@shopify/api-codegen-preset';

export default {
  schema: 'https://shopify.dev/admin-graphql-direct-proxy/2025-01',
  documents: ['app/**/*.{ts,tsx}'],
  projects: {
    default: shopifyApiProject({
      apiType: ApiType.Admin,
      apiVersion: '2025-01',
      documents: ['app/**/*.{ts,tsx}'],
      outputDir: './app/types',
    }),
  },
};

2. shopifyApiTypes() - Custom Projects

Provides the generates configuration for custom project setups:
import {ApiType, pluckConfig, shopifyApiTypes} from '@shopify/api-codegen-preset';

export default {
  schema: 'https://shopify.dev/admin-graphql-direct-proxy/2025-01',
  documents: ['app/**/*.{ts,tsx}'],
  projects: {
    default: {
      schema: 'https://shopify.dev/admin-graphql-direct-proxy/2025-01',
      documents: ['app/**/*.{ts,tsx}'],
      extensions: {
        codegen: {
          pluckConfig,
          generates: shopifyApiTypes({
            apiType: ApiType.Admin,
            apiVersion: '2025-01',
            outputDir: './app/types',
          }),
        },
      },
    },
  },
};

3. preset - Full Control

Low-level preset for complete control:
import {ApiType, pluckConfig, preset} from '@shopify/api-codegen-preset';

export default {
  schema: 'https://shopify.dev/admin-graphql-direct-proxy/2025-01',
  documents: ['**/*.{ts,tsx}'],
  projects: {
    default: {
      schema: 'https://shopify.dev/admin-graphql-direct-proxy/2025-01',
      documents: ['**/*.{ts,tsx}'],
      extensions: {
        codegen: {
          pluckConfig,
          generates: {
            './types/admin.schema.json': {
              plugins: ['introspection'],
              config: {minify: true},
            },
            './types/admin.types.d.ts': {
              plugins: ['typescript'],
            },
            './types/admin.generated.d.ts': {
              preset,
              presetConfig: {
                apiType: ApiType.Admin,
              },
            },
          },
        },
      },
    },
  },
};

API Types

The preset supports three Shopify APIs:
import {ApiType} from '@shopify/api-codegen-preset';

// Admin API
ApiType.Admin

// Storefront API
ApiType.Storefront

// Customer Account API
ApiType.Customer

Generated Files

The codegen process generates three files:
// Base TypeScript types from the GraphQL schema
export type Product = {
  id: string;
  title: string;
  handle: string;
  // ... all schema types
};

Usage with Clients

Once types are generated, your API clients automatically detect them:
import {createAdminApiClient} from '@shopify/admin-api-client';
import './types/admin.generated.d.ts';

const client = createAdminApiClient({...});

// Fully typed response
const {data} = await client.request(
  `#graphql
  query GetProducts($first: Int!) {
    products(first: $first) {
      edges {
        node {
          id
          title
        }
      }
    }
  }`,
  {variables: {first: 10}}
);

// data.products.edges is fully typed
data?.products.edges.forEach(({node}) => {
  console.log(node.title); // string
});

Advanced Configuration

Multiple APIs

Generate types for multiple APIs in one project:
import {ApiType, shopifyApiProject} from '@shopify/api-codegen-preset';
import type {IGraphQLConfig} from 'graphql-config';

const config: IGraphQLConfig = {
  projects: {
    // Admin API for backend
    default: shopifyApiProject({
      apiType: ApiType.Admin,
      apiVersion: '2025-01',
      documents: ['app/**/*.{ts,tsx}'],
      outputDir: './app/types',
    }),
    // Storefront API for UI extensions
    storefront: shopifyApiProject({
      apiType: ApiType.Storefront,
      apiVersion: '2025-01',
      documents: ['extensions/**/*.{ts,tsx}'],
      outputDir: './extensions/types',
    }),
  },
};

export default config;
Generate types for a specific project:
npm run graphql-codegen --project=storefront

Enums as Const Assertions

Avoid runtime enum imports by using const assertions:
export default {
  projects: {
    default: shopifyApiProject({
      apiType: ApiType.Admin,
      apiVersion: '2025-01',
      outputDir: './types',
      enumsAsConst: true,
    }),
  },
};
With enumsAsConst: true:
// Must import enum
import {MetafieldOwnerType} from './types/admin.types';

const variables = {
  ownerType: MetafieldOwnerType.Product
};

TypeScript Files Instead of Declarations

Generate .ts files to import enums in runtime code:
export default {
  projects: {
    default: shopifyApiProject({
      apiType: ApiType.Admin,
      apiVersion: '2025-01',
      outputDir: './types',
      declarations: false, // Generate .ts instead of .d.ts
    }),
  },
};
This allows:
import {ProductStatus} from './types/admin.types';

const status = ProductStatus.Active;
Generating .ts files may slightly increase bundle size, but enables runtime enum usage.

Shopify Functions

Enable autocompletion for Shopify Function schemas:
import fs from 'fs';
import {ApiType, shopifyApiProject} from '@shopify/api-codegen-preset';
import type {IGraphQLConfig} from 'graphql-config';

function getConfig(): IGraphQLConfig {
  const config: IGraphQLConfig = {
    projects: {
      default: shopifyApiProject({
        apiType: ApiType.Admin,
        apiVersion: '2025-01',
        documents: ['app/**/*.{ts,tsx}'],
        outputDir: './app/types',
      }),
    },
  };

  // Add projects for each Shopify Function
  const extensions = fs.readdirSync('./extensions');
  
  for (const entry of extensions) {
    const schema = `./extensions/${entry}/schema.graphql`;
    if (fs.existsSync(schema)) {
      config.projects[entry] = {
        schema,
        documents: [`./extensions/${entry}/**/*.graphql`],
      };
    }
  }

  return config;
}

export default getConfig();

Watch Mode

Auto-regenerate types on file changes:
npm run graphql-codegen -- --watch

Troubleshooting

No documents found

If codegen fails with “no documents found”:
  1. Ensure you have at least one #graphql tagged query
  2. Or set ignoreNoDocuments: true in config:
export default {
  schema: 'https://shopify.dev/admin-graphql-direct-proxy',
  documents: ['**/*.{ts,tsx}'],
  ignoreNoDocuments: true,
  projects: {...},
};

Unnamed operations

All operations must have names:
query {
  shop {
    name
  }
}

TypeScript not finding types

Ensure your tsconfig.json includes the output directory:
{
  "compilerOptions": {
    "types": ["./types"]
  },
  "include": [
    "**/*.ts",
    "**/*.tsx",
    "types/**/*"
  ]
}

Exported Utilities

pluckConfig

Configuration for extracting GraphQL operations from files:
import {pluckConfig} from '@shopify/api-codegen-preset';

// Enables #graphql and /* GraphQL */ tags

API Types

export enum ApiType {
  Admin = 'Admin',
  Storefront = 'Storefront',
  Customer = 'Customer',
}

Configuration Interfaces

export interface ShopifyApiProjectOptions {
  apiType: ApiType;
  apiVersion?: string;
  outputDir?: string;
  documents?: string[];
  module?: string;
  declarations?: boolean;
  apiKey?: string;
  enumsAsConst?: boolean;
}

Best Practices

Commit Generated Files: Commit the generated type files to your repository so team members don’t need to regenerate them.
Use Named Operations: Always name your queries and mutations for better type inference and debugging.
API Version Sync: Keep your codegen apiVersion in sync with your client’s API version to avoid type mismatches.

Examples

Basic Admin API

// .graphqlrc.ts
import {ApiType, shopifyApiProject} from '@shopify/api-codegen-preset';

export default {
  schema: 'https://shopify.dev/admin-graphql-direct-proxy/2025-01',
  documents: ['**/*.ts'],
  projects: {
    default: shopifyApiProject({
      apiType: ApiType.Admin,
      apiVersion: '2025-01',
      outputDir: './types',
    }),
  },
};

Multiple Projects

import {ApiType, shopifyApiProject} from '@shopify/api-codegen-preset';

export default {
  projects: {
    admin: shopifyApiProject({
      apiType: ApiType.Admin,
      apiVersion: '2025-01',
      documents: ['backend/**/*.ts'],
      outputDir: './backend/types',
    }),
    storefront: shopifyApiProject({
      apiType: ApiType.Storefront,
      apiVersion: '2025-01',
      documents: ['frontend/**/*.ts'],
      outputDir: './frontend/types',
    }),
  },
};

Next Steps

Admin API Client

Use generated types with the Admin API Client

Storefront API Client

Use generated types with the Storefront API Client

GraphQL Codegen Docs

Learn more about GraphQL Code Generator

Build docs developers (and LLMs) love