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
Install the preset
npm install --save-dev @shopify/api-codegen-preset
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' ,
}),
} ,
} ;
Add npm script
Add to your package.json: {
"scripts" : {
"graphql-codegen" : "graphql-codegen"
}
}
Tag your queries
const { data } = await client . request (
`#graphql
query GetProducts($first: Int!) {
products(first: $first) {
edges {
node {
id
title
}
}
}
}` ,
{ variables: { first: 10 }}
);
Configuration Options
The preset provides three levels of configuration:
1. shopifyApiProject() - Recommended
One-stop configuration for a complete codegen project:
The Shopify API to use: ApiType.Admin, ApiType.Storefront, or ApiType.Customer
API version to use (e.g., '2025-01'). Defaults to oldest stable version
Directory for generated type files
documents
string[]
default: "['**/*.{ts,tsx}']"
Glob patterns for files to parse
Override the module whose types will be augmented
Generate .d.ts files (true) or .ts files (false)
Generate enums as const assertions instead of TypeScript enums
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:
admin.types.d.ts
admin.schema.json
admin.generated.d.ts
// 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
});
import { createStorefrontApiClient } from '@shopify/storefront-api-client' ;
import './types/storefront.generated.d.ts' ;
const client = createStorefrontApiClient ({ ... });
const { data } = await client . request (
`#graphql
query GetProduct($handle: String!) {
product(handle: $handle) {
id
title
priceRange {
minVariantPrice {
amount
currencyCode
}
}
}
}` ,
{ variables: { handle: 'shoe' }}
);
// data.product is fully typed
console . log ( data ?. product . title );
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:
Without enumsAsConst
With enumsAsConst
// 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”:
Ensure you have at least one #graphql tagged query
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:
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