mrkeyoor.com_
Sat 08 Aug 21:00 UTC
npmCLI & Toolingupdated 08 Aug 2026

@hey-api/openapi-ts

@hey-api/openapi-ts is an ESM code generator that reads an OpenAPI document and writes TypeScript artifacts such as request and response types, callable SDK functions, runtime schemas, framework query helpers, mocks, and server stubs. A plugin list controls both what is generated and which HTTP client shape it targets, including Fetch, Axios, Angular, Next.js, Nuxt, Ky, and ofetch. It is a build-time tool, not a runtime HTTP client by itself, and the quality of its output depends heavily on operation IDs and schemas in your API contract.

Verdict

One of the broadest TypeScript-first OpenAPI generators, particularly when SDK, validation, query, and server plugins should share a contract. Adopt it with an exact version, generated-diff checks, and clear ownership of the OpenAPI document.

API stability2/5The project labels version 0.99.0 as initial development and explicitly tells users to pin an exact version, with migration notes for breaking releases. Its plugin architecture gives each concern a clear configuration surface, but changes can affect config names, generated filenames, SDK signatures, or client behavior. Even a stable generator API cannot shield consumers from contract-driven output changes, so upgrades require generated-diff review and type checking.
Docs5/5The official manual has a dedicated quick start, configuration reference, output explanation, migration section, client pages, plugin pages, integrations, and custom extension guidance. The package README includes CLI, programmatic, Vite, and configuration examples and clearly warns that output may be erased. The monorepo also includes runnable examples for Fetch, Axios, Ky, Angular, Next.js, TanStack Query, Fastify, and other combinations.
Maintenance5/5Version 0.99.0 was published in June 2026, GitHub reports a push on August 6, 2026, and the repository is not archived. The monorepo has active CI and coordinated packages for generators, clients, schemas, and shared code. GitHub's open_issues_count is 545, which includes issues and pull requests; that volume shows both an active project and a substantial support queue that adopters should search before reporting edge cases.
Ecosystem5/5The package records 3,886,261 weekly downloads and advertises more than 20 plugins. Official choices span Fetch, Axios, Angular, Ky, Next.js, Nuxt, and ofetch clients, plus TypeScript, SDK, schemas, Zod, Valibot, TanStack Query variants, Pinia Colada, Fastify, NestJS, oRPC, and MSW generation. That breadth is a major advantage, though several generated integrations require their corresponding runtime package.

Use it if

  • You own an OpenAPI contract and want typed SDK functions instead of hand-maintained fetch wrappers
  • You want one generation step to produce types plus Zod, Valibot, TanStack Query, MSW, Fastify, NestJS, or oRPC helpers
  • You need to select a client style such as Fetch, Axios, Angular, Next.js, Nuxt, Ky, or ofetch
  • Your CI and developers can standardize on Node 22.18 or newer and pin the generator exactly
Skip it if

Setup reality

Install the generator as an exact-pinned dev dependency, for example `npm install -D -E @hey-api/openapi-ts@0.99.0`. The current package requires Node 22.18.0 or newer and peers on TypeScript 5.5.3 or newer, including supported TypeScript 6 releases. Its JavaScript API is ESM-only, although configuration may be TypeScript, ESM, CommonJS, or another format supported by the loader. A useful setup has `openapi-ts.config.ts` with input, output, and an explicit plugin list, plus an npm script that runs `openapi-ts`; checking generated files into source control is a team choice, but CI should regenerate and fail on diffs if reproducibility matters. Inputs can be a local JSON or YAML path, a URL, a Hey API Registry identifier, or an in-memory OpenAPI object. Remote private specs need whatever authentication the input endpoint expects, and the docs mention disabling TLS verification for self-signed development endpoints, which should never become a general production setting. Generation writes into the configured output folder and can erase manual changes, so treat that directory as generated code. Plugin choices can introduce runtime packages: the Fetch example is self-contained, while Axios output expects axios and TanStack Query output expects the matching TanStack package in the consuming application. Post-process commands such as formatters must also be installed and can make output vary across machines if their versions float. The project is pre-1.0 and publishes migration notes, so exact pinning plus review of generated diffs is not optional busywork. Spec changes can rename functions, change nullability, or alter request shapes even when the generator version stays fixed.

Patterns

Generate a client directly from the CLIgenerate-from-cli

npx @hey-api/openapi-ts@0.99.0 -i ./openapi.yaml -o ./src/client

Pin the exact version in repeatable builds; the package is pre-1.0 and publishes breaking migration notes.

Create a typed generator configconfigure-local-spec

import { defineConfig } from '@hey-api/openapi-ts'

export default defineConfig({
  input: './openapi.yaml',
  output: './src/client',
})

The default plugins generate TypeScript interfaces and an SDK; use an explicit plugin list when output must stay predictable.

Run the checked-in configurationadd-generation-script

{
  "scripts": {
    "generate:api": "openapi-ts"
  }
}

Keep the config at the project root or pass the CLI's config option when using a nonstandard location.

Generate from a Node scriptgenerate-programmatically

import { createClient } from '@hey-api/openapi-ts'

await createClient({
  input: './openapi.yaml',
  output: './src/client',
})

The programmatic API is ESM-only and the package requires Node 22.18.0 or newer.

Generate a Fetch SDK and schemasgenerate-fetch-sdk

import { defineConfig } from '@hey-api/openapi-ts'

export default defineConfig({
  input: './openapi.yaml',
  output: './src/client',
  plugins: [
    '@hey-api/client-fetch',
    '@hey-api/schemas',
    '@hey-api/sdk',
    '@hey-api/typescript',
  ],
})

An explicit list replaces assumptions about default plugins and makes generated diffs easier to explain.

Target Axios instead of Fetchgenerate-axios-sdk

export default defineConfig({
  input: './openapi.yaml',
  output: './src/client',
  plugins: [
    '@hey-api/client-axios',
    '@hey-api/sdk',
    '@hey-api/typescript',
  ],
})

Install axios in the consuming application because the generated Axios client depends on it at runtime.

Generate TanStack React Query helpersgenerate-react-query

export default defineConfig({
  input: './openapi.yaml',
  output: './src/client',
  plugins: [
    '@hey-api/client-fetch',
    { name: '@hey-api/sdk', instance: true },
    '@hey-api/typescript',
    '@tanstack/react-query',
  ],
})

Install the matching @tanstack/react-query runtime package; plugin names distinguish framework-specific TanStack variants.

Post-process generated filesformat-generated-output

export default defineConfig({
  input: './openapi.yaml',
  output: {
    path: './src/client',
    postProcess: ['oxfmt', 'oxlint'],
  },
})

Every listed command must be installed and deterministic; floating formatter versions can create noisy generated diffs.

Set the generated service client defaultsconfigure-generated-client

import { client } from './client/client.gen'

client.setConfig({
  baseUrl: 'https://api.example.com',
  headers: { Authorization: `Bearer ${token}` },
})

A global mutable client can leak per-user credentials in server applications; use request-scoped clients there.

Create an isolated generated client instancecreate-local-client

import { createClient } from './client/client'

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

Pass this instance through an SDK call's client option when configuration must be scoped to a tenant or request.

Call a generated SDK operationcall-generated-operation

import { getPetById } from './client/sdk.gen'

const { data, error } = await getPetById({
  path: { petId: 42 },
})
if (error) throw new Error('API request failed')
console.log(data)

Function names and parameter groups come from the OpenAPI operation; inspect generated output rather than copying names from another spec.

Attach fresh credentials with an interceptoradd-auth-interceptor

client.interceptors.request.use((request) => {
  request.headers.set('Authorization', `Bearer ${getToken()}`)
  return request
})

On a server, avoid reading user-specific tokens from shared global state; create or pass a request-scoped client.

Alternatives

PackageRegistryPick it when
openapi-typescriptnpmChoose it when you want TypeScript types from OpenAPI with minimal generated runtime code
orvalnpmChoose it for a mature React Query and mock-oriented generator with a different configuration model
swagger-typescript-apinpmChoose it for template-driven TypeScript API client generation and direct customization
@openapitools/openapi-generator-clinpmChoose it when you need the broad language and framework catalog of OpenAPI Generator and accept its heavier toolchain