Type-safe OpenAPI client for complex and large APIs. Requests follow the document's parameter styles, media types and encodings exactly. Fluent paths, scoped CLI generation and an openapi-fetch adapter.
See the code
A type-safe OpenAPI client for complex and large APIs, whose requests follow the document's wire rules exactly.
Documentation · Getting started · Wire comparison · Changelog
openapi-chain compiles the serialization rules an OpenAPI document declares (parameter style,
explode, allowReserved and content, request media types, and form and multipart Encoding
Objects) and applies them to every request. A build-time CLI generates types and metadata scoped to
the paths you call, so large documents stay affordable to type-check and to ship. Calls use a fluent
path API with no generated endpoint code and no runtime dependencies.
The pnpm monorepo contains three publishable packages: openapi-chain,
@openapi-chain/cli, and @openapi-chain/query. The runtime
keeps its existing package name and entry points. See the
package migration guide for CLI and query import changes and release
availability.
The first request below uses the Items schema. Your chain follows
your own schema: static path segments become properties, {parameters} become function calls, and
HTTP methods become request functions.
openapi-chain/openapi-fetch applies the same
serialization to an existing openapi-fetch client
(adapter guide).Choose the strict client when your document declares non-default parameter styles, parameter
content, cookie parameters, non-JSON media types or form and multipart encoding, and the server
depends on them. Choose the CLI's scoped generation when a large document makes type-checking or
metadata delivery expensive. If your API only uses JSON bodies and default parameter styles,
openapi-fetch and openapi-chain's core are comparable in size and speed; pick the call style you
prefer. Without scoping, openapi-chain's fluent types cost more to check than openapi-fetch's on the
measured GitHub and Stripe documents.
For a published release with this API:
pnpm add openapi-chain
pnpm add -D @openapi-chain/cli
Save the Items document as openapi.json, then create openapi-chain.config.json:
{
"schema": "./openapi.json",
"outDir": "./src/generated/api",
"paths": ["/items/{id}"]
}
Generate types and metadata together:
pnpm exec openapi-chain generate
pnpm exec openapi-chain generate --check
In src/client.ts, use the generated scope and metadata for the first request:
import { createStrictClient } from 'openapi-chain/strict';
import { metadata } from './generated/api/metadata.js';
import type { ScopedPaths } from './generated/api/scope.js';
const api = createStrictClient<ScopedPaths>({
baseUrl: 'https://api.example.com',
metadata,
});
const item = await api.items('42').get();
console.log(item.name);
Replace the example URL with your service. The minimum supported application compiler is TypeScript 6.0.3; install it in a new application if TypeScript is not already present. CI pins 6.0.3 and 7.0.2. TypeScript 7.0.2 is recommended for large schemas and editor responsiveness. The CLI privately installs TypeScript 5.9.3 for generation, so this path needs no generator peer override. See compiler compatibility and path scoping.
These docs describe the current source API. The source manifests show the checkout versions: runtime, CLI, and query adapter. An installed npm release may expose a different API. To try this exact implementation, follow the local tarball consumer check. Generation produces declarations and metadata, not endpoint client code.
The package exports ESM and CommonJS. Its Node.js engine range is
^22.22.1 || ^24.11.0 || >=26.0.0. Browser use requires standard Fetch APIs and a bundler or ESM
setup; Chromium has an integration suite. Enable TypeScript strict mode and include DOM types. See
setup and compatibility.
| Need | Entry point | Runtime schema |
|---|---|---|
| Fluent typed calls with schema-free serialization defaults | openapi-chain → createClient | None |
| OpenAPI parameter styles, structured forms or multipart encoding | openapi-chain/strict → createStrictClient | Compiled metadata |
| Compile serialization metadata from an OpenAPI document | openapi-chain/metadata → compileOpenAPIMetadata | OpenAPI 3.0, 3.1 or 3.2 object |
| Keep openapi-fetch calls with the strict serializer | openapi-chain/openapi-fetch → withOpenAPISerialization | Compiled metadata |
Core requires an explicit contentType whenever a body is supplied. Strict can infer a single
declared concrete media type and implements additional serialization rules. Both expose the same
fluent path API and operation-local extensions. The programmatic compiler remains available for
manual workflows and OpenAPI 3.2 metadata; the official CLI currently generates OpenAPI 3.0/3.1
types and metadata. See the support matrix before choosing serialization
behavior.
The generated strict client above keeps the document, CLI and compiler out of browser bundles. For large schemas, follow the single-scope workflow.
For an existing core application, follow the migration guide and compare representative requests before switching. Core cannot detect missing serialization rules from erased types; HTTP 200 is not proof of a correct filter.
Generate paths and metadata from the same schema revision. Strict checks request structure and
supported wire encodings; it is not a JSON Schema validator. Response validation, authentication
and retries are application responsibilities.
By default, calls return parsed success data and throw HttpError for non-2xx responses. Use
throwOnError: false to receive a typed result instead:
import { createStrictClient } from 'openapi-chain/strict';
import { metadata } from './generated/api/metadata.js';
import type { ScopedPaths } from './generated/api/scope.js';
const api = createStrictClient<ScopedPaths>({
baseUrl: 'https://api.example.com',
metadata,
throwOnError: false,
});
try {
const result = await api.items('42').get();
if (result.ok) console.log(result.data.name);
else console.error(result.status, result.data.error);
} catch (error) {
// Network, cancellation, serialization and parsing failures still reject.
console.error(error);
}
Response types assume the server follows the schema. For runtime validation, binary data or
streaming, use a response extension. Core defaults to JSON/text parsing;
strict also returns ArrayBuffer for other media. See the full
response contract.
| Guide | Contents |
|---|---|
| Getting started | Installation, type generation and a runnable offline example |
| API reference | Client options, paths, bodies, errors, extensions and transports |
| Support and boundaries | Serialization matrix, metadata inference and platform limits |
| Troubleshooting | Common type, serialization, Fetch and response problems |
| Wire comparison | Requests openapi-chain and openapi-fetch send for the same OpenAPI declarations, verified by tests |
| openapi-fetch adapter | Strict serialization inside an existing openapi-fetch client, or for another HTTP client |
| Performance | Size budgets, client comparisons, benchmark methods and dated measurements |
| Architecture | Type model, package boundaries and source map |
| Development | Local setup, checks, browser tests and release workflow |
| Documentation index | All guides and historical qualification reports |
Start with CONTRIBUTING.md. Report bugs or request features in GitHub Issues; include the entry point, package version and a minimal schema. Report vulnerabilities through the security process.
The separate @openapi-chain/cli package provides the openapi-chain generate command for local
OpenAPI 3.0/3.1 JSON/YAML documents. One config produces full type declarations, scoped client
types, selected runtime metadata and a provenance manifest. generate --check detects drift without
writing files.
See the CLI guide and runnable scoped example. CLI dependencies remain separate from the runtime package and browser bundles.
TypeScript
68.6%
JavaScript
30.8%
Type-safe OpenAPI client for complex and large APIs. Requests follow the document's parameter styles, media types and encodings exactly. Fluent paths, scoped CLI generation and an openapi-fetch adapter.
See the code
A type-safe OpenAPI client for complex and large APIs, whose requests follow the document's wire rules exactly.
Documentation · Getting started · Wire comparison · Changelog
openapi-chain compiles the serialization rules an OpenAPI document declares (parameter style,
explode, allowReserved and content, request media types, and form and multipart Encoding
Objects) and applies them to every request. A build-time CLI generates types and metadata scoped to
the paths you call, so large documents stay affordable to type-check and to ship. Calls use a fluent
path API with no generated endpoint code and no runtime dependencies.
The pnpm monorepo contains three publishable packages: openapi-chain,
@openapi-chain/cli, and @openapi-chain/query. The runtime
keeps its existing package name and entry points. See the
package migration guide for CLI and query import changes and release
availability.
The first request below uses the Items schema. Your chain follows
your own schema: static path segments become properties, {parameters} become function calls, and
HTTP methods become request functions.
openapi-chain/openapi-fetch applies the same
serialization to an existing openapi-fetch client
(adapter guide).Choose the strict client when your document declares non-default parameter styles, parameter
content, cookie parameters, non-JSON media types or form and multipart encoding, and the server
depends on them. Choose the CLI's scoped generation when a large document makes type-checking or
metadata delivery expensive. If your API only uses JSON bodies and default parameter styles,
openapi-fetch and openapi-chain's core are comparable in size and speed; pick the call style you
prefer. Without scoping, openapi-chain's fluent types cost more to check than openapi-fetch's on the
measured GitHub and Stripe documents.
For a published release with this API:
pnpm add openapi-chain
pnpm add -D @openapi-chain/cli
Save the Items document as openapi.json, then create openapi-chain.config.json:
{
"schema": "./openapi.json",
"outDir": "./src/generated/api",
"paths": ["/items/{id}"]
}
Generate types and metadata together:
pnpm exec openapi-chain generate
pnpm exec openapi-chain generate --check
In src/client.ts, use the generated scope and metadata for the first request:
import { createStrictClient } from 'openapi-chain/strict';
import { metadata } from './generated/api/metadata.js';
import type { ScopedPaths } from './generated/api/scope.js';
const api = createStrictClient<ScopedPaths>({
baseUrl: 'https://api.example.com',
metadata,
});
const item = await api.items('42').get();
console.log(item.name);
Replace the example URL with your service. The minimum supported application compiler is TypeScript 6.0.3; install it in a new application if TypeScript is not already present. CI pins 6.0.3 and 7.0.2. TypeScript 7.0.2 is recommended for large schemas and editor responsiveness. The CLI privately installs TypeScript 5.9.3 for generation, so this path needs no generator peer override. See compiler compatibility and path scoping.
These docs describe the current source API. The source manifests show the checkout versions: runtime, CLI, and query adapter. An installed npm release may expose a different API. To try this exact implementation, follow the local tarball consumer check. Generation produces declarations and metadata, not endpoint client code.
The package exports ESM and CommonJS. Its Node.js engine range is
^22.22.1 || ^24.11.0 || >=26.0.0. Browser use requires standard Fetch APIs and a bundler or ESM
setup; Chromium has an integration suite. Enable TypeScript strict mode and include DOM types. See
setup and compatibility.
| Need | Entry point | Runtime schema |
|---|---|---|
| Fluent typed calls with schema-free serialization defaults | openapi-chain → createClient | None |
| OpenAPI parameter styles, structured forms or multipart encoding | openapi-chain/strict → createStrictClient | Compiled metadata |
| Compile serialization metadata from an OpenAPI document | openapi-chain/metadata → compileOpenAPIMetadata | OpenAPI 3.0, 3.1 or 3.2 object |
| Keep openapi-fetch calls with the strict serializer | openapi-chain/openapi-fetch → withOpenAPISerialization | Compiled metadata |
Core requires an explicit contentType whenever a body is supplied. Strict can infer a single
declared concrete media type and implements additional serialization rules. Both expose the same
fluent path API and operation-local extensions. The programmatic compiler remains available for
manual workflows and OpenAPI 3.2 metadata; the official CLI currently generates OpenAPI 3.0/3.1
types and metadata. See the support matrix before choosing serialization
behavior.
The generated strict client above keeps the document, CLI and compiler out of browser bundles. For large schemas, follow the single-scope workflow.
For an existing core application, follow the migration guide and compare representative requests before switching. Core cannot detect missing serialization rules from erased types; HTTP 200 is not proof of a correct filter.
Generate paths and metadata from the same schema revision. Strict checks request structure and
supported wire encodings; it is not a JSON Schema validator. Response validation, authentication
and retries are application responsibilities.
By default, calls return parsed success data and throw HttpError for non-2xx responses. Use
throwOnError: false to receive a typed result instead:
import { createStrictClient } from 'openapi-chain/strict';
import { metadata } from './generated/api/metadata.js';
import type { ScopedPaths } from './generated/api/scope.js';
const api = createStrictClient<ScopedPaths>({
baseUrl: 'https://api.example.com',
metadata,
throwOnError: false,
});
try {
const result = await api.items('42').get();
if (result.ok) console.log(result.data.name);
else console.error(result.status, result.data.error);
} catch (error) {
// Network, cancellation, serialization and parsing failures still reject.
console.error(error);
}
Response types assume the server follows the schema. For runtime validation, binary data or
streaming, use a response extension. Core defaults to JSON/text parsing;
strict also returns ArrayBuffer for other media. See the full
response contract.
| Guide | Contents |
|---|---|
| Getting started | Installation, type generation and a runnable offline example |
| API reference | Client options, paths, bodies, errors, extensions and transports |
| Support and boundaries | Serialization matrix, metadata inference and platform limits |
| Troubleshooting | Common type, serialization, Fetch and response problems |
| Wire comparison | Requests openapi-chain and openapi-fetch send for the same OpenAPI declarations, verified by tests |
| openapi-fetch adapter | Strict serialization inside an existing openapi-fetch client, or for another HTTP client |
| Performance | Size budgets, client comparisons, benchmark methods and dated measurements |
| Architecture | Type model, package boundaries and source map |
| Development | Local setup, checks, browser tests and release workflow |
| Documentation index | All guides and historical qualification reports |
Start with CONTRIBUTING.md. Report bugs or request features in GitHub Issues; include the entry point, package version and a minimal schema. Report vulnerabilities through the security process.
The separate @openapi-chain/cli package provides the openapi-chain generate command for local
OpenAPI 3.0/3.1 JSON/YAML documents. One config produces full type declarations, scoped client
types, selected runtime metadata and a provenance manifest. generate --check detects drift without
writing files.
See the CLI guide and runnable scoped example. CLI dependencies remain separate from the runtime package and browser bundles.
TypeScript
68.6%
JavaScript
30.8%