stacks/ts-open-api
publicClone
Push over the same URL. A password will not work: create a token under access tokens and use it in place of one.
- .config
- .github
- .vscode
- bin
- docs
- src
- test
- .editorconfig 147 B
- .gitattributes 12 B
- .gitignore 122 B
- build.ts 201 B
- bun.lock 35.0 KB
- bunfig.toml 88 B
- CHANGELOG.md 118 B
- CLAUDE.md 1.6 KB
- deps.yaml 32 B
- LICENSE.md 1.1 KB
- open-api 39 B
- open-api.config.ts 0 B
- package.json 3.5 KB
- README.md 10.4 KB
- tsconfig.json 627 B

ts-open-api
A blazingly fast, native OpenAPI to TypeScript type generator built with Bun. Generate TypeScript types from OpenAPI 3.0 schemas with zero runtime overhead.
Why ts-open-api
- ⚡️ 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
Features
- ✅ 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
Installation
# 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-apiQuick Start
CLI Usage
# 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-descriptionsProgrammatic Usage
import { generateTypes } from 'ts-open-api'
await generateTypes({
input: './openapi.json',
output: './api-types.ts',
alphabetize: true,
immutable: true,
includeDescriptions: true,
})Node.js API
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)CLI Options
| 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 |
Programmatic API Options
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
}Advanced Usage
Custom Transformations
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
},
})Post-Processing Generated Types
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}`
},
})Inject Custom Types
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
`,
})Custom Header
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
*/`,
})Examples
Generate Immutable Types with Descriptions
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
}Generate Alphabetized Types
open-api ./openapi.json --output ./api-types.ts --alphabetizeProgrammatic Generation with All Options
import { 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
},
})Integration with Build Tools
Package.json Scripts
{
"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"
}
}With Bun
// 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',
})Comparison with openapi-typescript
| 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 | ✅ | ✅ |
Testing
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
TypeScript Configuration
For best results, use these TypeScript settings:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler",
"noUncheckedIndexedAccess": true,
"strict": true
}
}Changelog
Please see our releases page for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Community
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
Postcardware
“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 🌎
Sponsors
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.
License
The MIT License (MIT). Please see LICENSE for more information.
Made with 💙