A blazingly fast, native OpenAPI to TypeScript type generator built with Bun. Generate TypeScript types from OpenAPI 3.0 schemas with zero runtime overhead.
- ⚡️ Lightning Fast - Built with Bun for maximum performance
- 🎯 Zero Runtime - Pure TypeScript types with no runtime dependencies
- 🔧 Highly Configurable - Extensive options for customizing output
- 📝 JSDoc Support - Generate rich documentation from your OpenAPI schemas
- 🎨 Transform API - Customize type generation with transform hooks
- 🧪 Well Tested - Comprehensive test suite with 26+ test cases
- 🚀 Native Implementation - No external dependencies for type generation
- ✅ Full OpenAPI 3.0 & 3.1 support
- ✅ Generate types from local or remote schemas
- ✅ Support for all schema types (objects, arrays, enums, unions, etc.)
- ✅ Schema composition (allOf, anyOf, oneOf)
- ✅ Reference resolution ($ref)
- ✅ Path parameters, query parameters, and headers
- ✅ Request bodies and responses
- ✅ JSDoc comments with descriptions and examples
- ✅ Readonly/immutable types
- ✅ Custom type transformations
- ✅ Alphabetical sorting
- ✅ CLI and programmatic API
# Using bun
bun add -D ts-open-api
# Using npm
npm install -D ts-open-api
# Using pnpm
pnpm add -D ts-open-api
# Using yarn
yarn add -D ts-open-api# Generate types from a local OpenAPI schema
open-api ./openapi.json --output ./api-types.ts
# Generate from a remote schema
open-api https://api.example.com/openapi.json --output ./api-types.ts
# With options
open-api ./openapi.json \
--output ./api-types.ts \
--alphabetize \
--immutable \
--include-descriptionsimport { generateTypes } from 'ts-open-api'
await generateTypes({
input: './openapi.json',
output: './api-types.ts',
alphabetize: true,
immutable: true,
includeDescriptions: true,
})import { OpenAPITypeScriptGenerator } from 'ts-open-api'
import type { OpenAPISchema } from 'ts-open-api'
const schema: OpenAPISchema = {
openapi: '3.0.0',
info: { title: 'My API', version: '1.0.0' },
paths: {
'/users': {
get: {
responses: {
'200': {
description: 'Success',
content: {
'application/json': {
schema: {
type: 'array',
items: { $ref: '#/components/schemas/User' },
},
},
},
},
},
},
},
},
components: {
schemas: {
User: {
type: 'object',
required: ['id', 'name'],
properties: {
id: { type: 'string' },
name: { type: 'string' },
email: { type: 'string' },
},
},
},
},
}
const generator = new OpenAPITypeScriptGenerator(schema, {
input: '',
output: '',
alphabetize: true,
})
const typescript = generator.generate()
console.log(typescript)| Option | Description | Default |
|---|---|---|
--output <path> |
Output file path | ./api-types.ts |
--alphabetize |
Sort types alphabetically | false |
--immutable |
Generate readonly properties | false |
--silent |
Suppress console output | false |
--export-type |
Use export type instead of export interface |
false |
--default-non-nullable |
Treat schema objects as non-nullable by default | false |
--additional-properties |
Allow arbitrary properties via index signature | false |
--path-params-as-types |
Generate path params as string literal types | false |
--support-array-length |
Support array length validation in types | false |
--no-header |
Disable header comment | false |
--include-descriptions |
Include descriptions as JSDoc comments | false |
--include-examples |
Include examples in JSDoc comments | false |
All CLI options are available in the programmatic API, plus additional advanced options:
interface GeneratorOptions {
input: string
output: string
// Type generation options
exportType?: boolean
alphabetize?: boolean
immutable?: boolean
additionalProperties?: boolean
defaultNonNullable?: boolean
pathParamsAsTypes?: boolean
supportArrayLength?: boolean
// Documentation options
includeDescriptions?: boolean
includeExamples?: boolean
// Header options
header?: boolean
headerComment?: string
// Output options
silent?: boolean
// Advanced options
transform?: (schema: SchemaObject) => SchemaObject
postTransform?: (typescript: string) => string
inject?: string
}Transform schemas before type generation:
await generateTypes({
input: './openapi.json',
output: './api-types.ts',
transform: (schema) => {
// Add custom logic to transform schemas
if (schema.type === 'string' && schema.format === 'date-time') {
// Convert all date-time strings to Date types
return { ...schema, type: 'string', tsType: 'Date' }
}
return schema
},
})Modify the generated TypeScript code:
await generateTypes({
input: './openapi.json',
output: './api-types.ts',
postTransform: (typescript) => {
// Add custom imports or modify generated code
return `import type { CustomType } from './custom'\n\n${typescript}`
},
})Add custom type definitions at the beginning of the file:
await generateTypes({
input: './openapi.json',
output: './api-types.ts',
inject: `
// Custom utility types
type Nullable<T> = T | null
type Optional<T> = T | undefined
`,
})Replace the default header comment:
await generateTypes({
input: './openapi.json',
output: './api-types.ts',
headerComment: `/**
* Custom API Types
* Generated on ${new Date().toISOString()}
* DO NOT EDIT MANUALLY
*/`,
})open-api ./openapi.json \
--output ./api-types.ts \
--immutable \
--include-descriptions \
--include-examplesOutput:
export interface User {
/** The unique identifier for the user */
readonly "id": string
/**
* The user's full name
* @example "John Doe"
*/
readonly "name": string
/** The user's email address */
readonly "email"?: string
}open-api ./openapi.json --output ./api-types.ts --alphabetizeimport { generateTypes } from 'ts-open-api'
await generateTypes({
input: './openapi.json',
output: './api-types.ts',
alphabetize: true,
immutable: true,
includeDescriptions: true,
includeExamples: true,
exportType: true,
transform: (schema) => {
// Custom transformations
return schema
},
postTransform: (ts) => {
// Post-process generated TypeScript
return ts
},
}){
"scripts": {
"generate-types": "open-api ./openapi.json --output ./src/api-types.ts",
"generate:watch": "open-api ./openapi.json --output ./src/api-types.ts --watch",
"prebuild": "bun run generate-types"
}
}// build.ts
import { generateTypes } from 'ts-open-api'
// Generate types before building
await generateTypes({
input: './api/openapi.json',
output: './src/generated/api-types.ts',
alphabetize: true,
})
// Continue with your build process
await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
})| Feature | ts-open-api | openapi-typescript |
|---|---|---|
| Runtime | Bun (faster) | Node.js |
| Dependencies | Zero for generation | Several |
| OpenAPI 3.0 | ✅ | ✅ |
| OpenAPI 3.1 | ✅ | ✅ |
| Transform API | ✅ | ✅ |
| JSDoc Support | ✅ | ✅ |
| Immutable Types | ✅ | ✅ |
| Alphabetization | ✅ | ❌ |
| Path Params | ✅ | ✅ |
| Native Code | ✅ | ❌ |
| Type Safety | ✅ | ✅ |
bun testThe project includes comprehensive tests covering:
- Basic schema types (string, number, boolean, array)
- Object types with properties
- Nested objects
- Enum types
- Nullable types
- Composition types (allOf, anyOf, oneOf)
- Reference resolution
- Path operations
- Parameters and request bodies
For best results, use these TypeScript settings:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler",
"noUncheckedIndexedAccess": true,
"strict": true
}
}Please see our releases page for more information on what has changed recently.
Please see CONTRIBUTING for details.
For help, discussion about best practices, or any other conversation that would benefit from being searchable:
For casual chit-chat with others using this package:
Join the Stacks Discord Server
“Software that is free, but hopes for a postcard.” We love receiving postcards from around the world showing where Stacks is being used! We showcase them on our website too.
Our address: Stacks.js, 12665 Village Ln #2306, Playa Vista, CA 90094, United States 🌎
We would like to extend our thanks to the following sponsors for funding Stacks development. If you are interested in becoming a sponsor, please reach out to us.
The MIT License (MIT). Please see LICENSE for more information.
Made with 💙
