# OpenAPI and Typed-Client Generation

> Emit an OpenAPI document from your schemas, fail CI when it drifts, and generate a typed client from it.

Source: [https://askrjs.com/docs/tooling/openapi](https://askrjs.com/docs/tooling/openapi)

Status: stable. Packages: @askrjs/askr.

**Published packages are authoritative.** Examples may lag behind a published contract. When guidance differs, verify the exports and TypeScript declarations in your installed package, then file an issue.

## Example

Generate the OpenAPI artifact from executable route schemas, check it for drift in CI, then generate the typed client from that checked artifact.

```tsx
askr openapi --output ./openapi.yaml
askr openapi --check --output ./openapi.yaml
askr generate ./openapi.yaml --output ./generated/api.ts
```

## Generate OpenAPI

askr openapi [--entry &lt;path&gt;] [--output &lt;path&gt;] loads a TypeScript module (default src/api.ts) whose default export exposes a toOpenApiDocument() method, and writes the result as deterministic YAML (default ./openapi.yml) atomically. Because the output is deterministic, running it twice against unchanged source produces byte-identical files, which is what makes the --check mode below meaningful.

## Check drift

askr openapi --check performs no writes at all: it exits unsuccessfully if the target YAML file is missing, or if it differs from the freshly generated document by even a single byte. That makes it a direct fit for a CI gate that fails a build the moment someone changes API-affecting code without regenerating and committing the artifact.

## Generate a client

askr generate produces an @askrjs/fetch typed client from an OpenAPI document, separate from the openapi command itself. Where askr openapi produces the contract, askr generate consumes it -- the natural sequence in a project is to regenerate the OpenAPI artifact first, then regenerate the client against it, so the two stay in lockstep.

## CI contract

A typical CI setup runs askr openapi --check as a required step before merge, so any handler or type change that shifts the API surface without a matching openapi.yml commit fails loudly. Because --entry and --output both have sane defaults (src/api.ts and ./openapi.yml), most projects don't need to pass any flags at all in the CI step -- the command only needs overrides when the API module or artifact path differs from convention.

## Documentation navigation

[Previous](https://askrjs.com/docs/tooling/add/index.md) | [Next](https://askrjs.com/docs/tooling/ssg/index.md)
