npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, πŸ‘‹, I’m Ryan HefnerΒ  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you πŸ™

Β© 2025 – Pkg Stats / Ryan Hefner

@azwebmaster/openapi-to-ts

v0.0.18

Published

> πŸš€ **Generate fully-typed TypeScript clients from OpenAPI specs in seconds**

Downloads

165

Readme

OpenAPI to TypeScript

πŸš€ Generate fully-typed TypeScript clients from OpenAPI specs in seconds

Transform your OpenAPI 3.0+ specifications into production-ready TypeScript clients with full type safety, IntelliSense support, and zero configuration.

npm version License: MIT

✨ Why This Generator?

  • 🎯 Zero Config: Works out of the box with any OpenAPI 3.0+ spec
  • πŸ”’ Type Safe: Full TypeScript support with discriminated unions, nullable types, and schema composition
  • ⚑ Fast: Built with ts-morph for lightning-fast code generation
  • πŸ› οΈ Developer Friendly: Rich JSDoc comments, IntelliSense, and error-free generated code
  • πŸ“¦ Modern: Uses Axios with modern TypeScript patterns and ES modules

πŸš€ Quick Start

Install

# For CLI usage (recommended)
npm install -g @azwebmaster/openapi-to-ts

# Or using bun
bun install -g @azwebmaster/openapi-to-ts

# For programmatic usage in your project
npm install @azwebmaster/openapi-to-ts
# or
bun add @azwebmaster/openapi-to-ts

CLI Usage (Recommended)

The CLI is the easiest way to generate TypeScript clients:

# Basic generation
openapi-to-ts generate ./api.yaml

# Generate from URL
openapi-to-ts generate https://api.example.com/openapi.json

# With custom options
openapi-to-ts generate ./api.yaml \
  --output ./src/api \
  --namespace MyAPI \
  --type-output file-per-type

# Preview what will be generated (dry run)
openapi-to-ts generate ./api.yaml --dry-run

# Show API information
openapi-to-ts info ./api.yaml

Programmatic Usage

For integration into build scripts or custom tooling:

import { generateFromSpec } from '@azwebmaster/openapi-to-ts';

await generateFromSpec({
  inputSpec: './api.yaml',
  outputDir: './generated/api',
  namespace: 'MyAPI',
  typeOutputMode: 'single-file'
});

Use Your Generated Client

import { createClient } from './generated/api';

const api = createClient('https://api.example.com', {
  headers: { Authorization: 'Bearer YOUR_TOKEN' }
});

// Fully typed with IntelliSense! πŸŽ‰
const users = await api.getUsers({ page: 1, limit: 10 });
const newUser = await api.createUser({
  email: '[email protected]',
  name: 'John Doe'
});

πŸ“– What You Get

Generated Files

generated/
β”œβ”€β”€ types.ts      # All TypeScript interfaces
β”œβ”€β”€ client.ts     # Axios-based API client
└── index.ts      # Exports and factory function

Example Generated Types

// types.ts
export interface User {
  id: string;
  email: string;
  name: string;
  avatar?: string | null;
  preferences?: UserPreferences;
}

export interface CreateUserRequest {
  email: string;
  name: string;
  password: string;
  age?: number;
}

Example Generated Client

// client.ts
export class MyAPIClient {
  constructor(baseURL: string, config?: AxiosRequestConfig) {
    this.client = axios.create({ baseURL, ...config });
  }

  async getUsers(params?: GetUsersParams): Promise<AxiosResponse<User[]>> {
    return this.client.get('/users', { params });
  }

  async createUser(data: CreateUserRequest): Promise<AxiosResponse<User>> {
    return this.client.post('/users', data);
  }
}

🎯 Advanced Features

Configuration File System

For complex projects, use .ott.json configuration files to manage multiple APIs and operation filtering:

# Initialize configuration from OpenAPI spec
openapi-to-ts init ./api.yaml

# List available operations
openapi-to-ts list

# Generate only selected operations
openapi-to-ts generate --config --operation-ids "getUsers,createUser"

Configuration files support:

  • Multiple APIs: Generate clients for different OpenAPI specs
  • Operation Filtering: Select only the operations you need
  • Persistent Settings: Save generation options for team collaboration
  • CI/CD Integration: Use config files in automated builds

Schema Composition Support

# OpenAPI spec
components:
  schemas:
    Pet:
      oneOf:
        - $ref: '#/components/schemas/Dog'
        - $ref: '#/components/schemas/Cat'
      discriminator:
        propertyName: petType
    Dog:
      allOf:
        - $ref: '#/components/schemas/BasePet'
        - type: object
          properties:
            breed: { type: string }
// Generated TypeScript
export type Pet = Dog | Cat;

export interface Dog extends BasePet {
  petType: "dog";
  breed: string;
}

// TypeScript narrows the type automatically! πŸŽ‰
pets.forEach(pet => {
  if (pet.petType === "dog") {
    console.log(pet.breed); // TypeScript knows this is a Dog
  }
});

Nullable Types & Union Types

// OpenAPI 3.0 nullable
avatar?: string | null;

// OpenAPI 3.1 type arrays
status: "active" | "inactive" | "pending";

// Complex unions with anyOf
vehicle: Car | Truck | Motorcycle;

Namespace Organization

// Organized by operationId namespaces
const api = createClient('https://api.example.com');

// Direct methods
await api.getUsers();
await api.createUser(data);

// Namespaced methods
await api.users.getProfile();
await api.users.updateSettings(data);
await api.admin.getSystemStats();

βš™οΈ Configuration File System

For complex projects or when you need to generate multiple API clients, use the configuration file system with .ott.json:

Initialize Configuration

# Create configuration from OpenAPI spec
openapi-to-ts init ./api.yaml

# With custom output directory
openapi-to-ts init ./api.yaml -o ./src/api

# From remote URL
openapi-to-ts init https://api.example.com/openapi.json

Configuration File Format

The generated .ott.json file contains:

{
  "apis": [
    {
      "name": "My API",
      "spec": "./api.yaml",
      "output": "./generated",
      "namespace": "MyAPI",
      "axiosInstance": "apiClient",
      "typeOutput": "single-file",
      "headers": {
        "Authorization": "Bearer ${API_TOKEN}"
      },
      "operationIds": [
        "getUsers",
        "createUser",
        "updateUser"
      ]
    }
  ]
}

Configuration Commands

# List available operations from config
openapi-to-ts list

# List operations for specific API (if multiple APIs)
openapi-to-ts list --api "My API"

# Generate using configuration file
openapi-to-ts generate --config

# Generate specific operations from CLI
openapi-to-ts generate --config --operation-ids "getUsers,createUser"

Benefits of Configuration Files

  • Operation Filtering: Generate only the operations you need
  • Multiple APIs: Manage multiple OpenAPI specs in one project
  • Persistent Settings: Save generation options for repeated use
  • Team Collaboration: Share configuration with your team
  • CI/CD Integration: Use config files in automated builds

πŸ› οΈ CLI Reference

Commands

# Generate TypeScript client
openapi-to-ts generate <spec> [options]

# Initialize configuration file
openapi-to-ts init <spec> [options]

# List operations from config
openapi-to-ts list [options]

# Show API specification info
openapi-to-ts info <spec>

# Show usage examples and tips
openapi-to-ts examples

Generate Command Options

| Option | Description | Default | |--------|-------------|---------| | -o, --output <dir> | Output directory for generated files | ./generated | | -n, --namespace <name> | Namespace for the generated client class | API | | -a, --axios-instance <name> | Name for the Axios instance variable | apiClient | | -t, --type-output <mode> | Type organization: single-file, file-per-type, group-by-tag | single-file | | -H, --header <header> | Add header for URL requests (format: "Name: Value") | - | | --dry-run | Preview generation without writing files | false |

CLI Examples

# Basic generation from local file
openapi-to-ts generate api.yaml

# Generate from remote URL
openapi-to-ts generate https://api.example.com/openapi.json

# Generate with authentication headers
openapi-to-ts generate https://api.example.com/openapi.json \
  -H "Authorization: Bearer your-token" \
  -H "X-API-Key: your-api-key"

# Generate with environment variable headers
openapi-to-ts generate https://api.example.com/openapi.json \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "X-API-Key: ${API_KEY:default-key}"

# Custom output directory and namespace
openapi-to-ts generate api.yaml -o ./src/api -n GitHubAPI

# Different type organization modes
openapi-to-ts generate api.yaml -t file-per-type    # One file per type
openapi-to-ts generate api.yaml -t group-by-tag     # Group by OpenAPI tags

# Preview what will be generated
openapi-to-ts generate api.yaml --dry-run

# Configuration file workflow
openapi-to-ts init api.yaml                         # Create .ott.json config
openapi-to-ts list                                  # List available operations
openapi-to-ts generate --config                     # Generate using config
openapi-to-ts generate --config --operation-ids "getUsers,createUser"  # Generate specific operations

# Show API specification information
openapi-to-ts info api.yaml
openapi-to-ts info https://api.example.com/openapi.json

# Get help and examples
openapi-to-ts examples
openapi-to-ts --help

Environment Variables in Headers

You can use environment variables in header values to keep sensitive information out of your configuration files and command history. This is especially useful for API keys, tokens, and other credentials.

Syntax

  • ${VAR_NAME} - Use the value of the environment variable VAR_NAME
  • ${VAR_NAME:default_value} - Use the environment variable VAR_NAME, or default_value if not set
  • ${VAR_NAME:} - Use the environment variable VAR_NAME, or empty string if not set

Examples

# Set environment variables
export API_TOKEN="your-secret-token"
export API_KEY="your-api-key"

# Use in CLI commands
openapi-to-ts generate https://api.example.com/openapi.json \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "X-API-Key: ${API_KEY}"

# With default values
openapi-to-ts generate https://api.example.com/openapi.json \
  -H "Authorization: Bearer ${API_TOKEN:guest}" \
  -H "X-API-Key: ${API_KEY:demo-key}"

Configuration Files

Environment variables also work in .ott.json configuration files:

{
  "apis": [
    {
      "name": "MyAPI",
      "spec": "https://api.example.com/openapi.json",
      "headers": {
        "Authorization": "Bearer ${API_TOKEN}",
        "X-API-Key": "${API_KEY:default-key}",
        "X-Environment": "${ENV:development}"
      }
    }
  ]
}

Security Best Practices

  • Never commit environment variables to version control
  • Use .env files for local development (not supported by this tool, use your shell or process manager)
  • Use default values for non-sensitive configuration
  • Keep sensitive tokens in secure environment variable management systems

Type Output Modes

  • single-file (default): All types in one types.ts file
  • file-per-type: Each type in its own file under types/ directory
  • group-by-tag: Types grouped by OpenAPI tags/categories

πŸ”§ Programmatic Usage

For integration into build scripts, CI/CD pipelines, or custom tooling:

import { generateFromSpec, TypeOutputMode } from '@azwebmaster/openapi-to-ts';

// Basic usage
await generateFromSpec({
  spec: './api.yaml',
  outputDir: './generated/api',
  namespace: 'MyAPI'
});

// Advanced usage with all options
await generateFromSpec({
  spec: 'https://api.example.com/openapi.json',
  outputDir: './src/generated',
  namespace: 'GitHubAPI',
  axiosInstanceName: 'githubClient',
  typeOutputMode: TypeOutputMode.FilePerType,
  headers: {
    'Authorization': 'Bearer ${API_TOKEN}',
    'X-API-Key': '${API_KEY:default-key}'
  },
  operationIds: ['getUsers', 'createUser', 'updateUser']
});

Generator Options

interface GeneratorOptions {
  spec: string;                         // Path to OpenAPI spec file or URL
  outputDir: string;                    // Output directory for generated files
  namespace?: string;                   // Client namespace (default: 'API')
  axiosInstanceName?: string;           // Name for Axios instance (default: 'apiClient')
  headers?: Record<string, string>;     // HTTP headers for remote specs
  typeOutputMode?: TypeOutputMode;      // How to organize generated types
  operationIds?: string[];              // Filter specific operations to generate
}

enum TypeOutputMode {
  SingleFile = 'single-file',           // All types in one file
  FilePerType = 'file-per-type',        // One file per type
  GroupByTag = 'group-by-tag'           // Group by OpenAPI tags
}

Build Script Integration

// scripts/generate-api.ts
import { generateFromSpec, TypeOutputMode } from '@azwebmaster/openapi-to-ts';

async function generateAPI() {
  try {
    await generateFromSpec({
      spec: './api/openapi.yaml',
      outputDir: './src/api/generated',
      namespace: 'MyAPI',
      typeOutputMode: TypeOutputMode.SingleFile,
      operationIds: ['getUsers', 'createUser', 'updateUser'] // Only generate specific operations
    });
    console.log('βœ… API client generated successfully');
  } catch (error) {
    console.error('❌ Failed to generate API client:', error);
    process.exit(1);
  }
}

generateAPI();
// package.json
{
  "scripts": {
    "generate:api": "tsx scripts/generate-api.ts",
    "build": "npm run generate:api && tsc"
  }
}

🎨 Supported OpenAPI Features

βœ… Schema Features

  • Composition: anyOf, oneOf, allOf
  • Discriminated Unions: With proper TypeScript narrowing
  • Nullable Types: OpenAPI 3.0 nullable and 3.1 type arrays
  • Const Values: Literal types
  • Enums: String and numeric unions
  • Inheritance: Schema extension with allOf

βœ… Type System

  • Primitives: string, number, boolean, integer
  • Arrays: Array<T> with typed items
  • Objects: Interfaces with required/optional properties
  • References: $ref resolution across components
  • Additional Properties: Record<string, T>

βœ… API Features

  • All HTTP Methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
  • Parameters: Path, query, header parameters
  • Request Bodies: Typed request data
  • Responses: Full response typing
  • Authentication: Header-based auth support

🎯 Real-World Example

Let's generate a client for a user management API:

# Generate the client
openapi-to-ts generate user-api.yaml -o ./src/api -n UserAPI
// Use the generated client
import { createClient } from './src/api';

const userAPI = createClient('https://api.myapp.com', {
  headers: { Authorization: `Bearer ${token}` }
});

// Get users with pagination
const { data } = await userAPI.getUsers({
  page: 1,
  limit: 20,
  sort: 'created_at',
  order: 'desc'
});

// Create a new user
const newUser = await userAPI.createUser({
  email: '[email protected]',
  name: 'John Doe',
  password: 'secure123',
  preferences: {
    theme: 'dark',
    notifications: { email: true, push: false }
  }
});

// Update user with partial data
await userAPI.patchUser({
  name: 'John Smith',
  preferences: { theme: 'light' }
});

🀝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/azwebmaster/openapi-to-ts.git
cd openapi-to-ts

# Install dependencies
bun install

# Run tests
bun test

# Build the project
bun run build

πŸ“„ License

MIT License - see LICENSE for details.

πŸ™ Acknowledgments

  • Built with ts-morph for powerful TypeScript manipulation
  • Uses @apidevtools/swagger-parser for OpenAPI parsing
  • Inspired by the TypeScript community's need for better API client generation

Made with ❀️ for the TypeScript community

Report an issue β€’ Request a feature β€’ View on GitHub