Skip to content

Configuration

Keep generation options typed, reviewable, and repeatable.

Put stable generation settings in typed-openapi.config.ts. defineConfig() gives editor completion, checks the configuration shape, and turns a long generation command into a reviewable project contract.

typed-openapi.config.ts
import { defineConfig } from "typed-openapi";
export default defineConfig({
input: "./openapi.yaml",
output: "./src/api/client.ts",
runtime: "zod",
validation: "strict",
validateSide: "both",
defaultFetcher: true,
tanstack: "query.ts",
msw: "msw.ts",
transformDates: true,
format: true,
});

Now one short command regenerates every configured output:

Terminal window
pnpm exec typed-openapi

Treat the OpenAPI file, config, and generated TypeScript as one reviewed change. That makes API drift visible in a normal pull request instead of at runtime.

When runtime is set, generation also writes a sibling .types.d.ts file by default. Commit or publish it with the runtime module. See runtime type sidecars for why this keeps large generated clients fast and how to opt out.

CLI flags win over config values. Keep the shared config checked in, then narrow a temporary build without copying it.

Terminal window
pnpm exec typed-openapi --endpoint '^/public(?:/|$)' --output src/api/public.ts

For a checked-in, domain-specific client, use endpointPatterns in the config. See filter endpoints and schemas for a complete catalog-client example.

Use JSON when TypeScript configuration is not desirable:

{
"input": "./openapi.yaml",
"runtime": "valibot",
"validation": "formats",
"defaultFetcher": true,
"coerce": true
}

The CLI auto-loads typed-openapi.config.ts, .mts, .js, .mjs, .json, .typed-openapi.json, or typed-openapi.json from the current working directory. Pass --config ./path/to/config.ts to select another file.

input and the main output are resolved from the command’s working directory, not from the config file’s directory. Companion names such as tanstack: "query.ts" are the exception: they resolve from the main output file’s directory.

Run the command from the package that owns the config when its input and output are package-relative. CLI flags still override the checked-in defaults, so the same config can generate a focused client for a one-off job.

Terminal window
# Run from the package that owns typed-openapi.config.ts.
pnpm --dir packages/web exec typed-openapi
# Or invoke from the repository root. In that case, paths inside the config must also be root-relative.
# For example: input: "./packages/web/openapi.yaml", output: "./packages/web/src/api/openapi.ts".
pnpm exec typed-openapi --config packages/web/typed-openapi.config.ts

Use a named preset for most projects. A policy object is available when a spec needs a deliberate exception:

export default defineConfig({
input: "./openapi.yaml",
runtime: "zod",
validation: { preset: "strict", stringConstraints: false, numberConstraints: false },
});

See validation depth and transforms for every policy field and preset default.

defaultFetcher can be a simple boolean or a small object when an application has its own file and environment conventions.

export default defineConfig({
input: "./openapi.yaml",
output: "./src/api/openapi.ts",
defaultFetcher: {
clientPath: "./openapi.ts",
envApiBaseUrl: "VITE_API_URL",
fetcherName: "fetchApi",
apiName: "api",
},
});
FieldWhat it changes
clientPathThe import specifier written into the generated fetcher. It is emitted verbatim; make it correct from the fetcher file.
envApiBaseUrlThe globalThis.process?.env key used by the generated default client. It does not read Vite or other bundler env objects.
fetcherNameThe exported fetch function name.
apiNameThe default exported client name and create…() factory name.

In a browser app, do not edit generated code or expect envApiBaseUrl to read import.meta.env. Create a client with the bundler value instead:

import { createApi } from "./api/api.client";
export const api = createApi(import.meta.env.VITE_API_URL);

tanstack, msw, and a string defaultFetcher output name are resolved relative to the main output file’s directory. With output: "./src/api/openapi.ts", use "query.ts" for src/api/query.ts or "../mocks/handlers.ts" for src/mocks/handlers.ts—not "./src/api/query.ts".