OpenAPI Code Generation Core Knowledge
SkillAI & modelsOpenAPI client code generation. Covers openapi-typescript, openapi-generator-cli, swagger-typescript-api, and trpc-openapi. Use for generating type-safe API clients.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the OpenAPI Code Generation Core Knowledge skill
What this skill tells your AI
The instructions your AI receives, as published by claude-dev-suite/claude-dev-suite in skills/api-integration/openapi-codegen/SKILL.md and read by ahel’s review.
Deep Knowledge: Use
mcp__documentation__fetch_docswith technology:openapi-codegenfor comprehensive documentation.
openapi-typescript (Types Only)
Generates TypeScript types from OpenAPI schemas. Lightweight, no runtime.
# Installation
npm install -D openapi-typescript
# Generate types
npx openapi-typescript ./openapi.yaml -o ./src/types/api.ts
npx openapi-typescript https://api.example.com/openapi.json -o ./src/types/api.ts
Generated Types Usage
import type { paths, components } from './types/api';
// Schema types
type User = components['schemas']['User'];
type CreateUserDto = components['schemas']['CreateUserDto'];
// Request/Response types
type CreateUserRequest = paths['/users']['post']['requestBody']['content']['application/json'];
type UserResponse = paths['/users/{id}']['get']['responses']['200']['content']['application/json'];
type UsersListResponse = paths['/users']['get']['responses']['200']['content']['application/json'];
// Path parameters
type UserPathParams = paths['/users/{id}']['get']['parameters']['path'];
With openapi-fetch
import createClient from 'openapi-fetch';
import type { paths } from './types/api';
const client = createClient<paths>({
baseUrl: 'https://api.example.com',
});
// Fully typed requests
const { data, error } = await client.GET('/users/{id}', {
params: { path: { id: '123' } },
});
const { data } = await client.POST('/users', {
body: { name: 'John', email: 'john@example.com' },
});
// Query parameters
const { data } = await client.GET('/users', {
params: { query: { status: 'active', page: 1 } },
});
openapi-generator-cli (Full Client)
Generates complete API clients with fetch/axios implementations.
# Installation
npm install -D @openapitools/openapi-generator-cli
# Generate TypeScript Fetch client
npx @openapitools/openapi-generator-cli generate \
-i openapi.yaml \
-g typescript-fetch \
-o ./src/api-client
# Generate TypeScript Axios client
npx @openapitools/openapi-generator-cli generate \
-i openapi.yaml \
-g typescript-axios \
-o ./src/api-client
Configuration File
# openapitools.json
{
"$schema": "https://raw.githubusercontent.com/OpenAPITools/openapi-generator-cli/master/apps/generator-cli/src/config.schema.json",
"spaces": 2,
"generator-cli": {
"version": "7.0.0",
"generators": {
"typescript-client": {
"generatorName": "typescript-fetch",
"output": "#{cwd}/src/api-client",
"inputSpec": "#{cwd}/openapi.yaml",
"additionalProperties": {
"supportsES6": true,
"npmName": "@myorg/api-client",
"typescriptThreePlus": true,
"withInterfaces": true
}
}
}
}
}
Generated Client Usage
import { Configuration, UsersApi } from './api-client';
const config = new Configuration({
basePath: 'https://api.example.com',
accessToken: () => localStorage.getItem('token') || '',
});
const usersApi = new UsersApi(config);
// Typed API calls
const users = await usersApi.listUsers({ status: 'active' });
const user = await usersApi.getUserById({ id: '123' });
const newUser = await usersApi.createUser({
createUserDto: { name: 'John', email: 'john@example.com' },
});
swagger-typescript-api
Fast, customizable generator with template support.
# Installation
npm install -D swagger-typescript-api
# Generate
npx swagger-typescript-api -p ./openapi.yaml -o ./src/api -n api.ts
Configuration
npx swagger-typescript-api \
-p ./openapi.yaml \
-o ./src/api \
-n api.ts \
--axios \ # Use axios instead of fetch
--modular \ # Separate files per tag
--route-types \ # Generate route types
--extract-request-body \ # Extract request body types
--extract-response-body # Extract response body types
Generated Client Usage
import { Api } from './api/api';
const api = new Api({
baseUrl: 'https://api.example.com',
securityWorker: () => ({
headers: { Authorization: `Bearer ${getToken()}` },
}),
});
// Typed API calls
const users = await api.users.usersList({ status: 'active' });
const user = await api.users.usersDetail('123');
const newUser = await api.users.usersCreate({
name: 'John',
email: 'john@example.com',
});
trpc-openapi (Export tRPC as OpenAPI)
Generate OpenAPI spec from tRPC router. Useful for external API consumers.
npm install trpc-openapi
Define OpenAPI Endpoints
import { initTRPC } from '@trpc/server';
import { OpenApiMeta } from 'trpc-openapi';
import { z } from 'zod';
const t = initTRPC.meta<OpenApiMeta>().create();
export const appRouter = t.router({
getUser: t.procedure
.meta({
openapi: {
method: 'GET',
path: '/users/{id}',
tags: ['users'],
summary: 'Get user by ID',
},
})
.input(z.object({ id: z.string() }))
.output(z.object({
id: z.string(),
name: z.string(),
email: z.string(),
}))
.query(({ input }) => getUserById(input.id)),
createUser: t.procedure
.meta({
openapi: {
method: 'POST',
path: '/users',
tags: ['users'],
summary: 'Create a new user',
},
})
.input(z.object({
name: z.string(),
email: z.string().email(),
}))
.output(z.object({
id: z.string(),
name: z.string(),
email: z.string(),
}))
.mutation(({ input }) => createUser(input)),
});
Generate OpenAPI Document
import { generateOpenApiDocument } from 'trpc-openapi';
import { appRouter } from './router';
const openApiDocument = generateOpenApiDocument(appRouter, {
title: 'My API',
version: '1.0.0',
baseUrl: 'https://api.example.com',
});
// Save to file
import fs from 'fs';
fs.writeFileSync('./openapi.json', JSON.stringify(openApiDocument, null, 2));
REST Handler
import { createOpenApiNextHandler } from 'trpc-openapi';
import { appRouter } from './router';
// Next.js API route: pages/api/[...trpc].ts
export default createOpenApiNextHandler({
router: appRouter,
createContext: () => ({}),
});
Production Readiness
CI/CD Integration
# .github/workflows/generate-client.yml
name: Generate API Client
on:
push:
paths:
- 'openapi.yaml'
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Generate types
run: npx openapi-typescript ./openapi.yaml -o ./src/types/api.ts
- name: Check for changes
id: check
run: |
if git diff --quiet src/types/api.ts; then
echo "changed=false" >> $GITHUB_OUTPUT
else
echo "changed=true" >> $GITHUB_OUTPUT
fi
- name: Commit and push
if: steps.check.outputs.changed == 'true'
run: |
git config --local user.email "bot@example.com"
git config --local user.name "API Generator Bot"
git add src/types/api.ts
git commit -m "chore: regenerate API types"
git push
Package Scripts
{
"scripts": {
"generate:types": "openapi-typescript ./openapi.yaml -o ./src/types/api.ts",
"generate:client": "openapi-generator-cli generate -c openapitools.json",
"generate:all": "npm run generate:types && npm run generate:client",
"precommit": "npm run generate:types && git add src/types/api.ts"
}
}
Watch Mode Development
# openapi-typescript with watch
npx openapi-typescript ./openapi.yaml -o ./src/types/api.ts --watch
# Or use nodemon
npx nodemon --watch openapi.yaml --exec "npx openapi-typescript ./openapi.yaml -o ./src/types/api.ts"
Validation Before Generation
# Validate spec first
npx @redocly/cli lint openapi.yaml
# Then generate
npx openapi-typescript ./openapi.yaml -o ./src/types/api.ts
Monitoring Metrics
| Metric | Target |
|---|---|
| Generated type coverage | 100% of endpoints |
| Build time with generation | < 30s |
| Type errors after generation | 0 |
| Spec validation errors | 0 |
Checklist
- OpenAPI spec validation in CI
- Automated type generation on spec changes
- Generated code committed or gitignored
- Version pinned for generator CLI
- Custom templates documented
- API client initialization documented
- Error handling patterns documented
- Authentication setup in client
- Breaking change detection
- Generated code tested
When NOT to Use This Skill
- Writing OpenAPI specifications (use
openapiskill) - GraphQL type generation (use
graphql-codegenskill) - tRPC type-safe APIs (use
trpcskill) - Manual API client implementation
- Simple APIs where manual types suffice
Anti-Patterns
| Anti-Pattern | Why It's Bad | Solution |
|---|---|---|
| Committing generated code to git | Merge conflicts, stale code | Add to .gitignore, generate in CI/build |
| Not versioning generator CLI | Inconsistent output | Pin generator versions in package.json |
| Editing generated files manually | Changes lost on regeneration | Extend or wrap generated code |
| No validation before generation | Invalid types generated | Validate spec with @redocly/cli first |
| Using different generators across team | Type inconsistencies | Standardize on one generator |
| Generating from remote spec without caching | Slow builds, network dependency | Cache spec locally or use schema registry |
| Not updating on spec changes | Type/runtime mismatch | Run generation in CI on spec updates |
| Missing error handling in generated code | Poor error UX | Wrap generated client with error handling |
Quick Troubleshooting
| Issue | Possible Cause | Solution |
|---|---|---|
| Generation fails | Invalid OpenAPI spec | Validate with @redocly/cli lint |
| Type errors after generation | Spec doesn't match API | Verify spec matches actual responses |
| Missing types | Spec incomplete or refs broken | Check all $refs resolve, add missing schemas |
| Wrong HTTP client generated | Generator config mismatch | Check -g flag or generator setting |
| Circular reference errors | Self-referencing schemas | Use discriminators or flatten schema |
| Slow generation | Large spec file | Use spec splitting or partial generation |
| Auth not working | Security scheme not configured | Add securityWorker or token config |
| "Cannot find module" errors | Generation didn't complete | Check for generation errors, rerun |
| Type conflicts | Multiple generators running | Use single generator, remove others |
Reference Documentation
Signals
- GitHub stars
- 33
- Forks
- 6
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
openapi-codegen- Source
- github.com/claude-dev-suite/claude-dev-suite