
OpenAPI 3.0–3.2 · no runtime dependenciesOpenAPI 3.0, 3.1 and 3.2 · ESM and CommonJS · no runtime dependencies
Type-safe OpenAPI requests that follow your document exactly
openapi-chain compiles the serialization rules an OpenAPI document declares and applies them to every request. A build-time CLI scopes types and metadata to the paths you call, so complex and large APIs stay correct and affordable.
Generate once
One config produces declarations, a path scope and matching runtime metadata. generate --check catches drift in CI.
{
"schema": "./openapi.json",
"outDir": "./src/generated/api",
"paths": ["/items/{id}"]
}pnpm exec openapi-chain generateCall with a fluent path
Static segments become properties and parameters become calls. Inputs and responses are typed from the selected operation.
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);What the document declares is what the server gets
For the same operation and input, openapi-fetch 0.17.0 sends a different request in 16 of 20 tested declarations. Every row is asserted by the repository's tests.
| Declaration | openapi-chain strict | openapi-fetch 0.17.0 |
|---|---|---|
| color: array, explode: false | ?color=blue,black,brown | ?color=blue&color=black&color=brown |
| id: array, style: label | /items/.3,4,5 | /items/3,4,5 |
| session: cookie parameter | cookie: session=abc | no Cookie header |
| form body with deepObject address | address%5Bcity%5D=Paris | address=%5Bobject+Object%5D |
Why teams choose it
Exact wire serialization
Parameter styles, explode, allowReserved, parameter content, media types and form or multipart Encoding Objects, from the document. Unsupported representations fail instead of guessing.
Scoped generation for large documents
On the pinned GitHub REST document, scoping a 40-operation consumer cut TypeScript 7 check time from 0.49 s to 0.045 s.
Keep openapi-fetch
withOpenAPISerialization applies the same serialization inside an existing openapi-fetch client; its types, middleware and results stay the same.
Small schema-free core
A 3.5 KiB gzip budget for the default client, with bundle size and request overhead in the same range as openapi-fetch.
When to choose openapi-chain
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 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; 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.