DocumentsHey API
OpenAPI TypeScript CLI
OpenAPI TypeScript CLI
Type
Topic
Status
Published
Created
Jun 5, 2026
Updated
Jun 5, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

OpenAPI TypeScript CLI (openapi-ts)#

Overview#

@hey-api/openapi-ts is a TypeScript code generator driven from a CLI (openapi-ts) or the programmatic createClient() API. The CLI entry point is src/run.ts, which calls runCli() from src/cli/index.ts. It accepts an OpenAPI spec (local file, URL, or inline object) and an output path, then runs configured plugins to generate TypeScript interfaces, SDK clients, and related artifacts.

Three invocation modes :

  • CLI: npx @hey-api/openapi-ts -i <spec> -o <output> or via an openapi-ts script in package.json
  • Node.js API: import { createClient } from '@hey-api/openapi-ts'
  • Vite plugin: @hey-api/vite-plugin

CLI Flags & Configuration#

The CLI is built on Commander.js. Flags are mapped to UserConfig by cliToConfig() in src/cli/adapter.ts.

FlagShortDescription
--input-iOpenAPI spec path, URL, or inline string
--output-oOutput folder(s)
--client-cHTTP client plugin to generate
--plugins-pPlugins to use
--file-fPath to config file
--debug-dEnable debug logging
--silent-sSuppress all output
--logs-lLogs folder path
--no-log-fileDisable log file output
--dry-runSkip writing files
--watch-wWatch for changes (interval in ms)

All flags are optional on the command line; missing values are resolved from a config file (default lookup via jiti/c12) .

Exit Code Behavior#

Exit codes are controlled in runCli() inside src/cli/index.ts.

ScenarioExit Code
Successful generation (no watch mode)0
Watch mode activeProcess stays alive; process.exit not called
Commander parse error (optionMissingArgument, unknownOption)Commander's own error.exitCode
Unexpected / unhandled error1

Successful run: after createClient() resolves, the CLI calls process.exit(0) only when no active watch is detected .

Commander errors: if Commander throws a CommanderError, runCli() prints a human-readable hint and exits with the exitCode embedded in the error :

  • commander.optionMissingArgument"Missing required argument. Run '...' --help for usage."
  • commander.unknownOption"Unknown option. Run '...' --help for available options."

Unexpected errors: any other caught exception logs "Unexpected error:" to stderr and exits 1 .

Error Handling & Input Failures#

Error classification happens in src/generate.ts and src/createClient.ts.

Input errors (file not found, HTTP 4xx)#

  • Missing local file: when $RefParser fails with ENOENT, createClient.ts catches it and throws InputError("Input file not found") .
  • HTTP 4xx on remote input: a 4xx response is treated as a client-side InputError (bad URL, missing auth, etc.) and includes the source path in the error .
  • HTTP 5xx: re-thrown as a generic Error — treated as a potential server bug .

Key behavior: generate.ts catches InputError specifically via getInputError() and returns an empty array ([]) instead of re-throwing . This means input errors do not propagate to runCli()'s catch block and do not trigger process.exit(1) — the process exits 0. The crash report and GitHub issue prompt are also suppressed for input errors .

Config validation errors#

ConfigValidationError is thrown before any jobs run when the resolved config is invalid. This does propagate out of generate.ts and will cause runCli() to exit 1.

Watch mode degradation#

In watch mode, errors on subsequent runs (after the first) do not throw — the CLI silently swallows fetch errors to handle cases where the server is temporarily unavailable .

Per-job errors#

Each job is wrapped in a try/catch; any thrown Error is wrapped in a JobError and re-thrown from generate.ts , ultimately reaching runCli() as an unexpected error → exit 1.

Input Validation (validate_EXPERIMENTAL)#

To validate the OpenAPI spec before generation, enable the experimental validator in the parser config :

export default {
  input: './openapi.json',
  output: 'src/client',
  parser: {
    validate_EXPERIMENTAL: true,
  },
};

When enabled, any detected errors in the input will exit @hey-api/openapi-ts and no plugins will be executed . The feature is currently limited in scope; additional use cases are tracked in GitHub issue #1970.

Key Source Files#

FilePurpose
src/run.tsCLI binary entry point; calls runCli()
src/cli/index.tsCommander setup, option definitions, runCli(), exit code logic
src/cli/adapter.tscliToConfig() — maps CLI flags to UserConfig
src/cli/schema.tsCliOptions interface
src/generate.tsTop-level createClient(), error classification, InputError suppression
src/createClient.tsPer-job execution: spec fetching, ENOENT detection, watch loop

Config reference: the full UserConfig type is defined in src/config/types.ts .