This is the abridged developer documentation for Hey API
# OpenAPI to code in seconds.
> Generate production-grade API infrastructure from your OpenAPI spec. SDKs, validators, query hooks, and 20+ plugins across TypeScript and Python. Free and open source.
[soon Python code generator](#email-cta) # OpenAPI to TypeScriptTypeScript✓ Python✓ in seconds. Production-grade API infrastructure. Typed SDKs, Zod schemas, TanStack Query hooks, and 20+ plugins. Free and open source. $ `npx @hey-api/openapi-ts` 3M downloads last week [Get Started ](https://heyapi.dev/docs/openapi/typescript/get-started) [View Demo ](https://stackblitz.com/edit/hey-api-example) types Zod Valibot SDK TanStack Query
```typescript
export type Order = {
id: string;
symbol: string;
side: 'buy' | 'sell';
type: 'market' | 'limit' | 'stop' | 'stop_limit';
quantity: number;
price?: number;
status: 'pending' | 'open' | 'filled' | 'partially_filled' | 'cancelled' | 'rejected';
createdAt: string;
};
export type CreateOrderData = {
body: Order;
};
export type CreateOrderResponse = Order;
```
```typescript
import { z } from 'zod';
export const zOrder = z.object({
id: z.string().uuid(),
symbol: z.string(),
side: z.enum(['buy', 'sell']),
type: z.enum(['market', 'limit', 'stop', 'stop_limit']),
quantity: z.number(),
price: z.number().optional(),
status: z.enum(['pending', 'open', 'filled', 'partially_filled', 'cancelled', 'rejected']),
createdAt: z.string().datetime(),
});
export type Order = z.infer;
```
```typescript
import * as v from 'valibot';
export const vOrder = v.object({
id: v.pipe(v.string(), v.uuid()),
symbol: v.string(),
side: v.picklist(['buy', 'sell']),
type: v.picklist(['market', 'limit', 'stop', 'stop_limit']),
quantity: v.number(),
price: v.optional(v.number()),
status: v.picklist(['pending', 'open', 'filled', 'partially_filled', 'cancelled', 'rejected']),
createdAt: v.pipe(v.string(), v.isoTimestamp()),
});
export type Order = v.InferOutput;
```
```typescript
import { createOrder } from './sdk.gen';
const { data, error } = await createOrder({
symbol: 'AAPL',
side: 'buy',
type: 'limit',
quantity: 10,
price: 189.5,
});
if (error) {
console.error('Order failed:', error.message);
return;
}
console.log('Order placed:', data.id);
```
```typescript
import { useMutation } from '@tanstack/react-query';
import { createOrderMutation } from './react-query.gen';
const { mutate, data, isPending } = useMutation({
...createOrderMutation(),
});
mutate({
body: {
symbol: 'AAPL',
side: 'buy',
type: 'limit',
quantity: 10,
price: 189.5,
},
});
```
Pydantic SDK
```python
from pydantic import BaseModel, AwareDatetime
from typing import Literal
from uuid import UUID
class Order(BaseModel):
id: UUID
symbol: str
side: Literal['buy', 'sell']
type: Literal['market', 'limit', 'stop', 'stop_limit']
quantity: float
price: float | None = None
status: Literal['pending', 'open', 'filled', 'partially_filled', 'cancelled', 'rejected']
createdAt: AwareDatetime
```
```python
from client import Client, CreateOrderData
client = Client()
order, error = client.create_order(CreateOrderData(
symbol='AAPL',
side='buy',
type='limit',
quantity=10,
price=189.50,
))
if error:
print(f'Order failed: {error.message}')
else:
print(f'Order placed: {order.id}')
```
GR  "OpenAPI codegen that just works." Guillermo Rauch CEO of Vercel Trusted by [ Vercel](https://vercel.com/blog/how-we-built-the-v0-ios-app) OpenCode PayPal Amazon Autodesk ## Up and running in minutes One config file. One command. Every time your spec changes. 01 / 04 Define your API 01 Define your API 02 Connect your spec 03 Compose your output 04 Use it ### Define your API Start with an existing spec or create one from scratch. OpenAPI is the foundation that powers everything.
```typescript
openapi: 3.2.0
info:
title: Equity Trading API
version: 1.2.0
paths:
/orders:
post:
operationId: createOrder
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
responses:
'201':
description: Order placed
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
```
### Connect your spec Pass a local path, remote URL, or an API registry shorthand. All valid OpenAPI versions and file formats supported, including inline spec objects.
```typescript
export default defineConfig({
input: 'https://api.tradespark.io/openapi.json',
output: 'src/trading-client',
});
```
### Compose your output Choose exactly what gets generated – nothing more, nothing less. Each plugin is independent and composable.
```typescript
export default defineConfig({
input: 'https://api.tradespark.io/openapi.json',
output: 'src/trading-client',
plugins: ['@hey-api/sdk', 'zod', '@tanstack/react-query'],
});
```
### Use it Run once or integrate into CI. Generated code is fully typed and deterministic. Same spec, same output, every time.
```typescript
import { createOrder, zOrder } from './trading-client';
const { data, error } = await createOrder({
body: {
symbol: 'AAPL',
side: 'buy',
type: 'limit',
quantity: 10,
price: 189.5,
},
});
if (error) {
console.error('Order rejected:', error.message);
return;
}
const order = zOrder.parse(data);
console.log(`Order ${order.id} is ${order.status}`);
```
Skip section ## Everything your API layer needs Pick what you need. Everything works together. ### SDKs & Types Typed SDK clients that regenerate as your API evolves. No handwritten interfaces to maintain. [Get started ](https://heyapi.dev/docs/openapi/typescript/get-started) ### Plugin Ecosystem From TanStack Query to Zod. Every plugin is opt-in, independently useful, and built to work together. [Explore plugins ](https://heyapi.dev/docs/openapi/typescript/core) ### HTTP Clients Native support for your runtime. Fetch API, Axios, Angular, Next.js, Nuxt, and more. [Explore clients ](https://heyapi.dev/docs/openapi/typescript/clients) ### Extensibility Build custom plugins and clients with the same APIs powering the built-ins. A platform, not a black box. [Build a plugin ](https://heyapi.dev/docs/openapi/typescript/plugins/custom) 20+ plugins available TanStack Query, Zod, Valibot, Fastify, and more. [Find your plugin ](https://heyapi.dev/docs/openapi/typescript/core) Skip section > The standard for API tooling. > > Every API tool forces a trade-off: quality, workflow, cost, or speed. Often more than one. I wanted to know what happens when you refuse to compromise. > > Hey API was built with one goal in mind: to be the last code generator you will ever need. Purpose-built from scratch, held to the standard the best engineering teams apply to their own codebase. > > The result of that work is yours, one install away. [L](https://linkedin.com/in/mrlubos) [](https://linkedin.com/in/mrlubos) [**Lubos** Founder, Hey API](https://linkedin.com/in/mrlubos) Honest take ## Not the right fit if… * — Your spec is broken or out of date. * — You're building a one-off integration, not a long-term API contract. * — You already have a codegen workflow that works. * — You want zero build steps. * — We don't support your language yet. If none of these apply, you'll probably love it. Coming soon ## Python is next. The ecosystem trusted by TypeScript developers is coming to Python codebases. Production-grade SDKs, Pydantic models, and more. Sign up for early access. Notify me ## Sponsors They make this possible. We make it worth sponsoring. gold * [](https://kutt.to/pkEZyc) [Best-in-class interfaces for developers and agents.](https://kutt.to/pkEZyc) * [The open source AI coding agent.](https://kutt.to/QM9Q2N) silver * [](https://kutt.to/skQUVd) * [](https://kutt.to/Dr9GuW) * [](https://kutt.to/yZVkdV) [Become a sponsor ](https://heyapi.dev/sponsors) ## Ready when you are. Player 1 OpenAPI Spec READY VS Player 2 Your Client READY? [Get Started ](https://heyapi.dev/docs/openapi/typescript/get-started)[View on GitHub ](https://github.com/hey-api/openapi-ts)
# OpenAPI to Python in seconds.
> Generate production-grade API infrastructure from your OpenAPI spec. Typed SDKs and Pydantic models. Free and open source.
[soon Python code generator](#email-cta) # OpenAPI to PythonTypeScript✓ Python✓ in seconds. Production-grade API infrastructure. Typed SDKs and Pydantic models. Free and open source. $ `npx @hey-api/openapi-python` [Get Started ](https://heyapi.dev/docs/openapi/python/get-started) [View Demo ](https://stackblitz.com/edit/hey-api-example) types Zod Valibot SDK TanStack Query
```typescript
export type Order = {
id: string;
symbol: string;
side: 'buy' | 'sell';
type: 'market' | 'limit' | 'stop' | 'stop_limit';
quantity: number;
price?: number;
status: 'pending' | 'open' | 'filled' | 'partially_filled' | 'cancelled' | 'rejected';
createdAt: string;
};
export type CreateOrderData = {
body: Order;
};
export type CreateOrderResponse = Order;
```
```typescript
import { z } from 'zod';
export const zOrder = z.object({
id: z.string().uuid(),
symbol: z.string(),
side: z.enum(['buy', 'sell']),
type: z.enum(['market', 'limit', 'stop', 'stop_limit']),
quantity: z.number(),
price: z.number().optional(),
status: z.enum(['pending', 'open', 'filled', 'partially_filled', 'cancelled', 'rejected']),
createdAt: z.string().datetime(),
});
export type Order = z.infer;
```
```typescript
import * as v from 'valibot';
export const vOrder = v.object({
id: v.pipe(v.string(), v.uuid()),
symbol: v.string(),
side: v.picklist(['buy', 'sell']),
type: v.picklist(['market', 'limit', 'stop', 'stop_limit']),
quantity: v.number(),
price: v.optional(v.number()),
status: v.picklist(['pending', 'open', 'filled', 'partially_filled', 'cancelled', 'rejected']),
createdAt: v.pipe(v.string(), v.isoTimestamp()),
});
export type Order = v.InferOutput;
```
```typescript
import { createOrder } from './sdk.gen';
const { data, error } = await createOrder({
symbol: 'AAPL',
side: 'buy',
type: 'limit',
quantity: 10,
price: 189.5,
});
if (error) {
console.error('Order failed:', error.message);
return;
}
console.log('Order placed:', data.id);
```
```typescript
import { useMutation } from '@tanstack/react-query';
import { createOrderMutation } from './react-query.gen';
const { mutate, data, isPending } = useMutation({
...createOrderMutation(),
});
mutate({
body: {
symbol: 'AAPL',
side: 'buy',
type: 'limit',
quantity: 10,
price: 189.5,
},
});
```
Pydantic SDK
```python
from pydantic import BaseModel, AwareDatetime
from typing import Literal
from uuid import UUID
class Order(BaseModel):
id: UUID
symbol: str
side: Literal['buy', 'sell']
type: Literal['market', 'limit', 'stop', 'stop_limit']
quantity: float
price: float | None = None
status: Literal['pending', 'open', 'filled', 'partially_filled', 'cancelled', 'rejected']
createdAt: AwareDatetime
```
```python
from client import Client, CreateOrderData
client = Client()
order, error = client.create_order(CreateOrderData(
symbol='AAPL',
side='buy',
type='limit',
quantity=10,
price=189.50,
))
if error:
print(f'Order failed: {error.message}')
else:
print(f'Order placed: {order.id}')
```
GR  "OpenAPI codegen that just works." Guillermo Rauch CEO of Vercel Trusted by [ Vercel](https://vercel.com/blog/how-we-built-the-v0-ios-app) OpenCode PayPal Amazon Autodesk ## Up and running in minutes One config file. One command. Every time your spec changes. 01 / 04 Define your API 01 Define your API 02 Connect your spec 03 Compose your output 04 Use it ### Define your API Start with an existing spec or create one from scratch. OpenAPI is the foundation that powers everything.
```typescript
openapi: 3.2.0
info:
title: Equity Trading API
version: 1.2.0
paths:
/orders:
post:
operationId: createOrder
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
responses:
'201':
description: Order placed
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
```
### Connect your spec Pass a local path, remote URL, or an API registry shorthand. All valid OpenAPI versions and file formats supported, including inline spec objects.
```typescript
export default defineConfig({
input: 'https://api.tradespark.io/openapi.json',
output: 'src/trading-client',
});
```
### Compose your output Choose exactly what gets generated – nothing more, nothing less. Each plugin is independent and composable.
```typescript
export default defineConfig({
input: 'https://api.tradespark.io/openapi.json',
output: 'src/trading-client',
plugins: ['@hey-api/sdk', 'zod', '@tanstack/react-query'],
});
```
### Use it Run once or integrate into CI. Generated code is fully typed and deterministic. Same spec, same output, every time.
```typescript
import { createOrder, zOrder } from './trading-client';
const { data, error } = await createOrder({
body: {
symbol: 'AAPL',
side: 'buy',
type: 'limit',
quantity: 10,
price: 189.5,
},
});
if (error) {
console.error('Order rejected:', error.message);
return;
}
const order = zOrder.parse(data);
console.log(`Order ${order.id} is ${order.status}`);
```
Skip section ## Everything your API layer needs Pick what you need. Everything works together. ### SDKs & Types Typed SDK clients that regenerate as your API evolves. No handwritten interfaces to maintain. [Get started ](https://heyapi.dev/docs/openapi/typescript/get-started) ### Plugin Ecosystem From TanStack Query to Zod. Every plugin is opt-in, independently useful, and built to work together. [Explore plugins ](https://heyapi.dev/docs/openapi/typescript/core) ### HTTP Clients Native support for your runtime. Fetch API, Axios, Angular, Next.js, Nuxt, and more. [Explore clients ](https://heyapi.dev/docs/openapi/typescript/clients) ### Extensibility Build custom plugins and clients with the same APIs powering the built-ins. A platform, not a black box. [Build a plugin ](https://heyapi.dev/docs/openapi/typescript/plugins/custom) 20+ plugins available TanStack Query, Zod, Valibot, Fastify, and more. [Find your plugin ](https://heyapi.dev/docs/openapi/typescript/core) Skip section > The standard for API tooling. > > Every API tool forces a trade-off: quality, workflow, cost, or speed. Often more than one. I wanted to know what happens when you refuse to compromise. > > Hey API was built with one goal in mind: to be the last code generator you will ever need. Purpose-built from scratch, held to the standard the best engineering teams apply to their own codebase. > > The result of that work is yours, one install away. [L](https://linkedin.com/in/mrlubos) [](https://linkedin.com/in/mrlubos) [**Lubos** Founder, Hey API](https://linkedin.com/in/mrlubos) Honest take ## Not the right fit if… * — Your spec is broken or out of date. * — You're building a one-off integration, not a long-term API contract. * — You already have a codegen workflow that works. * — You want zero build steps. * — We don't support your language yet. If none of these apply, you'll probably love it. Coming soon ## Python is next. The ecosystem trusted by TypeScript developers is coming to Python codebases. Production-grade SDKs, Pydantic models, and more. Sign up for early access. Notify me ## Sponsors They make this possible. We make it worth sponsoring. gold * [](https://kutt.to/pkEZyc) [Best-in-class interfaces for developers and agents.](https://kutt.to/pkEZyc) * [The open source AI coding agent.](https://kutt.to/QM9Q2N) silver * [](https://kutt.to/skQUVd) * [](https://kutt.to/Dr9GuW) * [](https://kutt.to/yZVkdV) [Become a sponsor ](https://heyapi.dev/sponsors) ## Ready when you are. Player 1 OpenAPI Spec READY VS Player 2 Your Client READY? [Get Started ](https://heyapi.dev/docs/openapi/python/get-started)[View on GitHub ](https://github.com/hey-api/openapi-ts)
# OpenAPI to TypeScript in seconds.
> Generate production-grade API infrastructure from your OpenAPI spec. Typed SDKs, Zod schemas, TanStack Query hooks, and 20+ plugins. Free and open source.
[soon Python code generator](#email-cta) # OpenAPI to TypeScriptTypeScript✓ Python✓ in seconds. Production-grade API infrastructure. Typed SDKs, Zod schemas, TanStack Query hooks, and 20+ plugins. Free and open source. $ `npx @hey-api/openapi-ts` 3M downloads last week [Get Started ](https://heyapi.dev/docs/openapi/typescript/get-started) [View Demo ](https://stackblitz.com/edit/hey-api-example) types Zod Valibot SDK TanStack Query
```typescript
export type Order = {
id: string;
symbol: string;
side: 'buy' | 'sell';
type: 'market' | 'limit' | 'stop' | 'stop_limit';
quantity: number;
price?: number;
status: 'pending' | 'open' | 'filled' | 'partially_filled' | 'cancelled' | 'rejected';
createdAt: string;
};
export type CreateOrderData = {
body: Order;
};
export type CreateOrderResponse = Order;
```
```typescript
import { z } from 'zod';
export const zOrder = z.object({
id: z.string().uuid(),
symbol: z.string(),
side: z.enum(['buy', 'sell']),
type: z.enum(['market', 'limit', 'stop', 'stop_limit']),
quantity: z.number(),
price: z.number().optional(),
status: z.enum(['pending', 'open', 'filled', 'partially_filled', 'cancelled', 'rejected']),
createdAt: z.string().datetime(),
});
export type Order = z.infer;
```
```typescript
import * as v from 'valibot';
export const vOrder = v.object({
id: v.pipe(v.string(), v.uuid()),
symbol: v.string(),
side: v.picklist(['buy', 'sell']),
type: v.picklist(['market', 'limit', 'stop', 'stop_limit']),
quantity: v.number(),
price: v.optional(v.number()),
status: v.picklist(['pending', 'open', 'filled', 'partially_filled', 'cancelled', 'rejected']),
createdAt: v.pipe(v.string(), v.isoTimestamp()),
});
export type Order = v.InferOutput;
```
```typescript
import { createOrder } from './sdk.gen';
const { data, error } = await createOrder({
symbol: 'AAPL',
side: 'buy',
type: 'limit',
quantity: 10,
price: 189.5,
});
if (error) {
console.error('Order failed:', error.message);
return;
}
console.log('Order placed:', data.id);
```
```typescript
import { useMutation } from '@tanstack/react-query';
import { createOrderMutation } from './react-query.gen';
const { mutate, data, isPending } = useMutation({
...createOrderMutation(),
});
mutate({
body: {
symbol: 'AAPL',
side: 'buy',
type: 'limit',
quantity: 10,
price: 189.5,
},
});
```
Pydantic SDK
```python
from pydantic import BaseModel, AwareDatetime
from typing import Literal
from uuid import UUID
class Order(BaseModel):
id: UUID
symbol: str
side: Literal['buy', 'sell']
type: Literal['market', 'limit', 'stop', 'stop_limit']
quantity: float
price: float | None = None
status: Literal['pending', 'open', 'filled', 'partially_filled', 'cancelled', 'rejected']
createdAt: AwareDatetime
```
```python
from client import Client, CreateOrderData
client = Client()
order, error = client.create_order(CreateOrderData(
symbol='AAPL',
side='buy',
type='limit',
quantity=10,
price=189.50,
))
if error:
print(f'Order failed: {error.message}')
else:
print(f'Order placed: {order.id}')
```
GR  "OpenAPI codegen that just works." Guillermo Rauch CEO of Vercel Trusted by [ Vercel](https://vercel.com/blog/how-we-built-the-v0-ios-app) OpenCode PayPal Amazon Autodesk ## Up and running in minutes One config file. One command. Every time your spec changes. 01 / 04 Define your API 01 Define your API 02 Connect your spec 03 Compose your output 04 Use it ### Define your API Start with an existing spec or create one from scratch. OpenAPI is the foundation that powers everything.
```typescript
openapi: 3.2.0
info:
title: Equity Trading API
version: 1.2.0
paths:
/orders:
post:
operationId: createOrder
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
responses:
'201':
description: Order placed
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
```
### Connect your spec Pass a local path, remote URL, or an API registry shorthand. All valid OpenAPI versions and file formats supported, including inline spec objects.
```typescript
export default defineConfig({
input: 'https://api.tradespark.io/openapi.json',
output: 'src/trading-client',
});
```
### Compose your output Choose exactly what gets generated – nothing more, nothing less. Each plugin is independent and composable.
```typescript
export default defineConfig({
input: 'https://api.tradespark.io/openapi.json',
output: 'src/trading-client',
plugins: ['@hey-api/sdk', 'zod', '@tanstack/react-query'],
});
```
### Use it Run once or integrate into CI. Generated code is fully typed and deterministic. Same spec, same output, every time.
```typescript
import { createOrder, zOrder } from './trading-client';
const { data, error } = await createOrder({
body: {
symbol: 'AAPL',
side: 'buy',
type: 'limit',
quantity: 10,
price: 189.5,
},
});
if (error) {
console.error('Order rejected:', error.message);
return;
}
const order = zOrder.parse(data);
console.log(`Order ${order.id} is ${order.status}`);
```
Skip section ## Everything your API layer needs Pick what you need. Everything works together. ### SDKs & Types Typed SDK clients that regenerate as your API evolves. No handwritten interfaces to maintain. [Get started ](https://heyapi.dev/docs/openapi/typescript/get-started) ### Plugin Ecosystem From TanStack Query to Zod. Every plugin is opt-in, independently useful, and built to work together. [Explore plugins ](https://heyapi.dev/docs/openapi/typescript/core) ### HTTP Clients Native support for your runtime. Fetch API, Axios, Angular, Next.js, Nuxt, and more. [Explore clients ](https://heyapi.dev/docs/openapi/typescript/clients) ### Extensibility Build custom plugins and clients with the same APIs powering the built-ins. A platform, not a black box. [Build a plugin ](https://heyapi.dev/docs/openapi/typescript/plugins/custom) 20+ plugins available TanStack Query, Zod, Valibot, Fastify, and more. [Find your plugin ](https://heyapi.dev/docs/openapi/typescript/core) Skip section > The standard for API tooling. > > Every API tool forces a trade-off: quality, workflow, cost, or speed. Often more than one. I wanted to know what happens when you refuse to compromise. > > Hey API was built with one goal in mind: to be the last code generator you will ever need. Purpose-built from scratch, held to the standard the best engineering teams apply to their own codebase. > > The result of that work is yours, one install away. [L](https://linkedin.com/in/mrlubos) [](https://linkedin.com/in/mrlubos) [**Lubos** Founder, Hey API](https://linkedin.com/in/mrlubos) Honest take ## Not the right fit if… * — Your spec is broken or out of date. * — You're building a one-off integration, not a long-term API contract. * — You already have a codegen workflow that works. * — You want zero build steps. * — We don't support your language yet. If none of these apply, you'll probably love it. Coming soon ## Python is next. The ecosystem trusted by TypeScript developers is coming to Python codebases. Production-grade SDKs, Pydantic models, and more. Sign up for early access. Notify me ## Sponsors They make this possible. We make it worth sponsoring. gold * [](https://kutt.to/pkEZyc) [Best-in-class interfaces for developers and agents.](https://kutt.to/pkEZyc) * [The open source AI coding agent.](https://kutt.to/QM9Q2N) silver * [](https://kutt.to/skQUVd) * [](https://kutt.to/Dr9GuW) * [](https://kutt.to/yZVkdV) [Become a sponsor ](https://heyapi.dev/sponsors) ## Ready when you are. Player 1 OpenAPI Spec READY VS Player 2 Your Client READY? [Get Started ](https://heyapi.dev/docs/openapi/typescript/get-started)[View on GitHub ](https://github.com/hey-api/openapi-ts)
# Clients
> HTTP clients for Hey API. Compatible with all our features.
We all send HTTP requests in a slightly different way. Hey API doesn’t force you to use any specific technology. What we do, however, is support your choice with great clients. All seamlessly integrated with our other features. ## Features [Section titled “Features”](#features) * seamless integration with `@hey-api/openapi-ts` ecosystem * type-safe response data and errors * response data validation and transformation * access to the original request and response * granular request and response customization options * minimal learning curve thanks to extending the underlying technology * support bundling inside the generated output ## Plugins [Section titled “Plugins”](#plugins) Hey API natively supports the following clients. * [Fetch API](https://heyapi.dev/docs/openapi/typescript/clients/fetch) * [Angular](https://heyapi.dev/docs/openapi/typescript/clients/angular) * [Axios](https://heyapi.dev/docs/openapi/typescript/clients/axios) * [Ky](https://heyapi.dev/docs/openapi/typescript/clients/ky) * [Next.js](https://heyapi.dev/docs/openapi/typescript/clients/next-js) * [Nuxt](https://heyapi.dev/docs/openapi/typescript/clients/nuxt) * [OFetch](https://heyapi.dev/docs/openapi/typescript/clients/ofetch) * [Effect](https://heyapi.dev/docs/openapi/typescript/clients/effect) Vote * [Got](https://heyapi.dev/docs/openapi/typescript/clients/got) Vote Don’t see your client? [Build your own](https://heyapi.dev/docs/openapi/typescript/clients/custom) or let us know your interest by [opening an issue](https://github.com/hey-api/openapi-ts/issues). ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Angular v19 Client
> Generate a type-safe Angular v19 client from OpenAPI with the Angular client for openapi-ts. Fully compatible with validators, transformers, and all core features.
Beta [Leave feedback](https://github.com/hey-api/openapi-ts/issues) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) ### About [Section titled “About”](#about) [Angular](https://angular.dev/) is a web framework that empowers developers to build fast, reliable applications. The Angular client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ### Collaborators [Section titled “Collaborators”](#collaborators) * [ Max Scopp](https://github.com/max-scopp) ## Features [Section titled “Features”](#features) * Angular v19 support * seamless integration with `@hey-api/openapi-ts` ecosystem * type-safe response data and errors * support for [`@Injectable()`](https://angular.dev/api/core/Injectable) decorators * response data validation and transformation * access to the original request and response * granular request and response customization options * minimal learning curve thanks to extending the underlying technology * support bundling inside the generated output ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@hey-api/client-angular` to your plugins and you’ll be ready to generate client artifacts. 🎉 * config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: ['@hey-api/client-angular'],
};
```
* cli
```sh
npx @hey-api/openapi-ts \
-i hey-api/backend \
-o src/client \
-c @hey-api/client-angular
```
### Providers [Section titled “Providers”](#providers) You can use the Angular client in your application by adding `provideHeyApiClient` to your providers. src/app/app.module.ts
```ts
import { provideHeyApiClient, client } from './client/client.gen';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withFetch()),
provideHeyApiClient(client),
],
};
```
## Configuration [Section titled “Configuration”](#configuration) The Angular client is built as a thin wrapper on top of Angular, extending its functionality to work with Hey API. If you’re already familiar with Angular, configuring your client will feel like working directly with Angular. When we installed the client above, it created a [`client.gen.ts`](https://heyapi.dev/docs/openapi/typescript/output#client) file. You will most likely want to configure the exported `client` instance. There are two ways to do that. ### `setConfig()` [Section titled “setConfig()”](#setconfig) This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any `HttpRequest` configuration option to `setConfig()`, and even your own [`httpClient`](#custom-httpclient) implementation. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
baseUrl: 'https://example.com',
});
```
The disadvantage of this approach is that your code may call the `client` instance before it’s configured for the first time. Depending on your use case, you might need to use the second approach. ### Runtime API [Section titled “Runtime API”](#runtime-api) Since `client.gen.ts` is a generated file, we can’t directly modify it. Instead, we can tell our configuration to use a custom file implementing the Runtime API. We do that by specifying the `runtimeConfigPath` option. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
name: '@hey-api/client-angular',
runtimeConfigPath: './src/hey-api.ts',
},
],
};
```
In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values. src/hey-api.ts
```ts
import type { CreateClientConfig } from './client/client.gen';
export const createClientConfig: CreateClientConfig = (config) => ({
...config,
baseUrl: 'https://example.com',
});
```
With this approach, `client.gen.ts` will call `createClientConfig()` before initializing the `client` instance. If needed, you can still use `setConfig()` to update the client configuration later. ### `createClient()` [Section titled “createClient()”](#createclient) You can also create your own client instance. You can use it to manually send requests or point it to a different domain. src/index.ts
```js
import { createClient } from './client/client';
const myClient = createClient({
baseUrl: 'https://example.com',
});
```
You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`. src/index.ts
```js
const response = await getFoo({
client: myClient,
});
```
### SDKs [Section titled “SDKs”](#sdks) Alternatively, you can pass the client configuration options to each SDK function. This is useful if you don’t want to create a client instance for one-off use cases. src/index.ts
```js
const response = await getFoo({
baseUrl: 'https://example.com', // <-- override default configuration
});
```
## `@Injectable` [Section titled “@Injectable”](#injectable) If you prefer to use the [`@Injectable()`](https://angular.dev/api/core/Injectable) decorators, set the `asClass` option in your SDK plugin to `true`. * example src/foo.service.ts
```ts
@Injectable({ providedIn: 'root' })
export class FooService {
// class methods
}
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
'@hey-api/client-angular',
{
name: '@hey-api/sdk',
asClass: true,
},
],
};
```
## Interceptors [Section titled “Interceptors”](#interceptors) Caution This section is under construction. We appreciate your patience. ## Auth [Section titled “Auth”](#auth) Caution This section is under construction. We appreciate your patience. ## Build URL [Section titled “Build URL”](#build-url) If you need to access the compiled URL, you can use the `buildUrl()` method. It’s loosely typed by default to accept almost any value; in practice, you will want to pass a type hint. src/index.ts
```ts
type FooData = {
path: {
fooId: number;
};
query?: {
bar?: string;
};
url: '/foo/{fooId}';
};
const url = client.buildUrl({
path: {
fooId: 1,
},
query: {
bar: 'baz',
},
url: '/foo/{fooId}',
});
console.log(url); // prints '/foo/1?bar=baz'
```
## Custom Instance [Section titled “Custom Instance”](#custom-instance) You can provide a custom `httpClient` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
httpClient: inject(CustomHttpClient),
});
```
You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be. ## Plugins [Section titled “Plugins”](#plugins) You might be also interested in the [Angular](https://heyapi.dev/docs/openapi/typescript/plugins/angular/v19) plugin. ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/client-angular/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Angular v20 Client
> Generate a type-safe Angular v20 client from OpenAPI with the Angular client for openapi-ts. Fully compatible with validators, transformers, and all core features.
Beta [Leave feedback](https://github.com/hey-api/openapi-ts/issues) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) ### About [Section titled “About”](#about) [Angular](https://angular.dev/) is a web framework that empowers developers to build fast, reliable applications. The Angular client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ### Collaborators [Section titled “Collaborators”](#collaborators) * [ Max Scopp](https://github.com/max-scopp) ## Features [Section titled “Features”](#features) * Angular v20 support * seamless integration with `@hey-api/openapi-ts` ecosystem * type-safe response data and errors * support for [`@Injectable()`](https://angular.dev/api/core/Injectable) decorators * response data validation and transformation * access to the original request and response * granular request and response customization options * minimal learning curve thanks to extending the underlying technology * support bundling inside the generated output ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@hey-api/client-angular` to your plugins and you’ll be ready to generate client artifacts. 🎉 * config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: ['@hey-api/client-angular'],
};
```
* cli
```sh
npx @hey-api/openapi-ts \
-i hey-api/backend \
-o src/client \
-c @hey-api/client-angular
```
### Providers [Section titled “Providers”](#providers) You can use the Angular client in your application by adding `provideHeyApiClient` to your providers. src/app/app.module.ts
```ts
import { provideHeyApiClient, client } from './client/client.gen';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withFetch()),
provideHeyApiClient(client),
],
};
```
## Configuration [Section titled “Configuration”](#configuration) The Angular client is built as a thin wrapper on top of Angular, extending its functionality to work with Hey API. If you’re already familiar with Angular, configuring your client will feel like working directly with Angular. When we installed the client above, it created a [`client.gen.ts`](https://heyapi.dev/docs/openapi/typescript/output#client) file. You will most likely want to configure the exported `client` instance. There are two ways to do that. ### `setConfig()` [Section titled “setConfig()”](#setconfig) This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any `HttpRequest` configuration option to `setConfig()`, and even your own [`httpClient`](#custom-instance) implementation. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
baseUrl: 'https://example.com',
});
```
The disadvantage of this approach is that your code may call the `client` instance before it’s configured for the first time. Depending on your use case, you might need to use the second approach. ### Runtime API [Section titled “Runtime API”](#runtime-api) Since `client.gen.ts` is a generated file, we can’t directly modify it. Instead, we can tell our configuration to use a custom file implementing the Runtime API. We do that by specifying the `runtimeConfigPath` option. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
name: '@hey-api/client-angular',
runtimeConfigPath: './src/hey-api.ts',
},
],
};
```
In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values. src/hey-api.ts
```ts
import type { CreateClientConfig } from './client/client.gen';
export const createClientConfig: CreateClientConfig = (config) => ({
...config,
baseUrl: 'https://example.com',
});
```
With this approach, `client.gen.ts` will call `createClientConfig()` before initializing the `client` instance. If needed, you can still use `setConfig()` to update the client configuration later. ### `createClient()` [Section titled “createClient()”](#createclient) You can also create your own client instance. You can use it to manually send requests or point it to a different domain. src/index.ts
```js
import { createClient } from './client/client';
const myClient = createClient({
baseUrl: 'https://example.com',
});
```
You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`. src/index.ts
```js
const response = await getFoo({
client: myClient,
});
```
### SDKs [Section titled “SDKs”](#sdks) Alternatively, you can pass the client configuration options to each SDK function. This is useful if you don’t want to create a client instance for one-off use cases. src/index.ts
```js
const response = await getFoo({
baseUrl: 'https://example.com', // <-- override default configuration
});
```
## `@Injectable` [Section titled “@Injectable”](#injectable) If you prefer to use the [`@Injectable()`](https://angular.dev/api/core/Injectable) decorators, set the `asClass` option in your SDK plugin to `true`. * example src/foo.service.ts
```ts
@Injectable({ providedIn: 'root' })
export class FooService {
// class methods
}
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
'@hey-api/client-angular',
{
name: '@hey-api/sdk',
asClass: true,
},
],
};
```
## Interceptors [Section titled “Interceptors”](#interceptors) Caution This section is under construction. We appreciate your patience. ## Auth [Section titled “Auth”](#auth) Caution This section is under construction. We appreciate your patience. ## Build URL [Section titled “Build URL”](#build-url) If you need to access the compiled URL, you can use the `buildUrl()` method. It’s loosely typed by default to accept almost any value; in practice, you will want to pass a type hint. src/index.ts
```ts
type FooData = {
path: {
fooId: number;
};
query?: {
bar?: string;
};
url: '/foo/{fooId}';
};
const url = client.buildUrl({
path: {
fooId: 1,
},
query: {
bar: 'baz',
},
url: '/foo/{fooId}',
});
console.log(url); // prints '/foo/1?bar=baz'
```
## Custom Instance [Section titled “Custom Instance”](#custom-instance) You can provide a custom `httpClient` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
httpClient: inject(CustomHttpClient),
});
```
You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be. ## Plugins [Section titled “Plugins”](#plugins) You might be also interested in the [Angular](https://heyapi.dev/docs/openapi/typescript/plugins/angular) plugin. ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/client-angular/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Axios v1 Client
> Generate a type-safe Axios v1 client from OpenAPI with the Axios client for openapi-ts. Fully compatible with validators, transformers, and all core features.
### About [Section titled “About”](#about) [Axios](https://axios-http.com) is a simple promise based HTTP client for the browser and Node.js. Axios provides a simple to use library in a small package with a very extensible interface. The Axios client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ### Demo [Section titled “Demo”](#demo) Launch demo ## Features [Section titled “Features”](#features) * Axios v1 support * seamless integration with `@hey-api/openapi-ts` ecosystem * type-safe response data and errors * response data validation and transformation * access to the original request and response * granular request and response customization options * minimal learning curve thanks to extending the underlying technology * support bundling inside the generated output ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@hey-api/client-axios` to your plugins and you’ll be ready to generate client artifacts. 🎉 * config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: ['@hey-api/client-axios'],
};
```
* cli
```sh
npx @hey-api/openapi-ts \
-i hey-api/backend \
-o src/client \
-c @hey-api/client-axios
```
## Configuration [Section titled “Configuration”](#configuration) The Axios client is built as a thin wrapper on top of Axios, extending its functionality to work with Hey API. If you’re already familiar with Axios, configuring your client will feel like working directly with Axios. When we installed the client above, it created a [`client.gen.ts`](https://heyapi.dev/docs/openapi/typescript/output#client) file. You will most likely want to configure the exported `client` instance. There are two ways to do that. ### `setConfig()` [Section titled “setConfig()”](#setconfig) This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Axios configuration option to `setConfig()` (except for `auth`), and even your own [Axios](#custom-instance) implementation. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
baseURL: 'https://example.com',
});
```
The disadvantage of this approach is that your code may call the `client` instance before it’s configured for the first time. Depending on your use case, you might need to use the second approach. ### Runtime API [Section titled “Runtime API”](#runtime-api) Since `client.gen.ts` is a generated file, we can’t directly modify it. Instead, we can tell our configuration to use a custom file implementing the Runtime API. We do that by specifying the `runtimeConfigPath` option. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
name: '@hey-api/client-axios',
runtimeConfigPath: './src/hey-api.ts',
},
],
};
```
In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values. src/hey-api.ts
```ts
import type { CreateClientConfig } from './client/client.gen';
export const createClientConfig: CreateClientConfig = (config) => ({
...config,
baseURL: 'https://example.com',
});
```
With this approach, `client.gen.ts` will call `createClientConfig()` before initializing the `client` instance. If needed, you can still use `setConfig()` to update the client configuration later. ### `createClient()` [Section titled “createClient()”](#createclient) You can also create your own client instance. You can use it to manually send requests or point it to a different domain. src/index.ts
```js
import { createClient } from './client/client';
const myClient = createClient({
baseURL: 'https://example.com',
});
```
You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`. src/index.ts
```js
const response = await getFoo({
client: myClient,
});
```
### SDKs [Section titled “SDKs”](#sdks) Alternatively, you can pass the client configuration options to each SDK function. This is useful if you don’t want to create a client instance for one-off use cases. src/index.ts
```js
const response = await getFoo({
baseURL: 'https://example.com', // <-- override default configuration
});
```
## Interceptors [Section titled “Interceptors”](#interceptors) Interceptors (middleware) can be used to modify requests before they’re sent or responses before they’re returned to your application. Axios provides interceptors, please refer to their documentation on [interceptors](https://axios-http.com/docs/interceptors). We expose the Axios instance through the `instance` field. src/index.ts
```js
import { client } from 'client/client.gen';
client.instance.interceptors.request.use((config) => {
// do something
return config;
});
```
## Auth [Section titled “Auth”](#auth) The SDKs include auth mechanisms for every endpoint. You will want to configure the `auth` field to pass the right token for each request. The `auth` field can be a string or a function returning a string representing the token. The returned value will be attached only to requests that require auth. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
auth: () => '',
baseURL: 'https://example.com',
});
```
If you’re not using SDKs or generating auth, using interceptors is a common approach to configuring auth for each request. src/index.ts
```js
import { client } from 'client/client.gen';
client.instance.interceptors.request.use((config) => {
config.headers.set('Authorization', 'Bearer ');
return config;
});
```
## Build URL [Section titled “Build URL”](#build-url) If you need to access the compiled URL, you can use the `buildUrl()` method. It’s loosely typed by default to accept almost any value; in practice, you will want to pass a type hint. src/index.ts
```ts
type FooData = {
path: {
fooId: number;
};
query?: {
bar?: string;
};
url: '/foo/{fooId}';
};
const url = client.buildUrl({
path: {
fooId: 1,
},
query: {
bar: 'baz',
},
url: '/foo/{fooId}',
});
console.log(url); // prints '/foo/1?bar=baz'
```
## Custom Instance [Section titled “Custom Instance”](#custom-instance) You can provide a custom `axios` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether. src/index.ts
```js
import axios from 'axios';
import { client } from 'client/client.gen';
// Customize the default axios instance
axios.defaults.baseURL = 'https://example.com';
client.setConfig({
axios: axios,
});
```
or you can pass an `AxiosInstance` created with `axios.create()`: src/index.ts
```js
import axios from 'axios';
import { client } from 'client/client.gen';
const customAxiosInstance = axios.create({
baseURL: 'https://example.com',
});
client.setConfig({
axios: customAxiosInstance,
});
```
You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be. ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/client-axios/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Custom Client
> Learn how to create your own Hey API client.
Caution Client API is in development. The interface might change before it becomes stable. We encourage you to leave feedback on [GitHub](https://github.com/hey-api/openapi-ts/issues/1213). You may need to write your own client if the available clients do not suit your needs or you’re working on a proprietary use case. This can be easily achieved using the Client API. But don’t take our word for it – all Hey API clients are written this way! Caution Custom clients documentation will be finalized after further testing. Simplified [instructions](https://github.com/hey-api/openapi-ts/issues/1213#issuecomment-2765206344) can be found in the GitHub thread. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Effect client
> Effect client for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/2082) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 105](https://github.com/hey-api/openapi-ts/issues/2082) ### About [Section titled “About”](#about) [Effect](https://effect.website/) is a powerful TypeScript library designed to help developers easily create complex, synchronous, and asynchronous programs.
# Fetch API Client
> Generate a type-safe Fetch API client from OpenAPI with the Fetch API client for openapi-ts. Fully compatible with validators, transformers, and all core features.
### About [Section titled “About”](#about) The [Fetch API](https://developer.mozilla.org/docs/Web/API/Fetch_API) provides an interface for fetching resources (including across the network). It is a more powerful and flexible replacement for XMLHttpRequest. The Fetch API client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ### Demo [Section titled “Demo”](#demo) Launch demo ## Features [Section titled “Features”](#features) * seamless integration with `@hey-api/openapi-ts` ecosystem * type-safe response data and errors * response data validation and transformation * access to the original request and response * granular request and response customization options * minimal learning curve thanks to extending the underlying technology * support bundling inside the generated output ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@hey-api/client-fetch` to your plugins and you’ll be ready to generate client artifacts. 🎉 * config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: ['@hey-api/client-fetch'],
};
```
* cli
```sh
npx @hey-api/openapi-ts \
-i hey-api/backend \
-o src/client \
-c @hey-api/client-fetch
```
## Configuration [Section titled “Configuration”](#configuration) The Fetch client is built as a thin wrapper on top of Fetch API, extending its functionality to work with Hey API. If you’re already familiar with Fetch, configuring your client will feel like working directly with Fetch API. When we installed the client above, it created a [`client.gen.ts`](https://heyapi.dev/docs/openapi/typescript/output#client) file. You will most likely want to configure the exported `client` instance. There are two ways to do that. ### `setConfig()` [Section titled “setConfig()”](#setconfig) This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Fetch API configuration option to `setConfig()`, and even your own [Fetch](#custom-instance) implementation. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
baseUrl: 'https://example.com',
});
```
The disadvantage of this approach is that your code may call the `client` instance before it’s configured for the first time. Depending on your use case, you might need to use the second approach. ### Runtime API [Section titled “Runtime API”](#runtime-api) Since `client.gen.ts` is a generated file, we can’t directly modify it. Instead, we can tell our configuration to use a custom file implementing the Runtime API. We do that by specifying the `runtimeConfigPath` option. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
name: '@hey-api/client-fetch',
runtimeConfigPath: './src/hey-api.ts',
},
],
};
```
In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values. src/hey-api.ts
```ts
import type { CreateClientConfig } from './client/client.gen';
export const createClientConfig: CreateClientConfig = (config) => ({
...config,
baseUrl: 'https://example.com',
});
```
With this approach, `client.gen.ts` will call `createClientConfig()` before initializing the `client` instance. If needed, you can still use `setConfig()` to update the client configuration later. ### `createClient()` [Section titled “createClient()”](#createclient) You can also create your own client instance. You can use it to manually send requests or point it to a different domain. src/index.ts
```js
import { createClient } from './client/client';
const myClient = createClient({
baseUrl: 'https://example.com',
});
```
You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`. src/index.ts
```js
const response = await getFoo({
client: myClient,
});
```
### SDKs [Section titled “SDKs”](#sdks) Alternatively, you can pass the client configuration options to each SDK function. This is useful if you don’t want to create a client instance for one-off use cases. src/index.ts
```js
const response = await getFoo({
baseUrl: 'https://example.com', // <-- override default configuration
});
```
## Interceptors [Section titled “Interceptors”](#interceptors) Interceptors (middleware) can be used to modify requests before they’re sent or responses before they’re returned to your application. They can be added with `use`, removed with `eject`, and updated wth `update`. The `use` and `update` methods will return the ID of the interceptor for use with `eject` and `update`. Fetch API does not have the interceptor functionality, so we implement our own. ### Example: Request interceptor [Section titled “Example: Request interceptor”](#example-request-interceptor) * use src/index.ts
```js
import { client } from 'client/client.gen';
async function myInterceptor(request) {
// do something
return request;
}
interceptorId = client.interceptors.request.use(myInterceptor);
```
* eject src/index.ts
```js
import { client } from 'client/client.gen';
// eject by ID
client.interceptors.request.eject(interceptorId);
// eject by reference
client.interceptors.request.eject(myInterceptor);
```
* update src/index.ts
```js
import { client } from 'client/client.gen';
async function myNewInterceptor(request) {
// do something
return request;
}
// update by ID
client.interceptors.request.update(interceptorId, myNewInterceptor);
// update by reference
client.interceptors.request.update(myInterceptor, myNewInterceptor);
```
### Example: Response interceptor [Section titled “Example: Response interceptor”](#example-response-interceptor) * use src/index.ts
```js
import { client } from 'client/client.gen';
async function myInterceptor(response) {
// do something
return response;
}
interceptorId = client.interceptors.response.use(myInterceptor);
```
* eject src/index.ts
```js
import { client } from 'client/client.gen';
// eject by ID
client.interceptors.response.eject(interceptorId);
// eject by reference
client.interceptors.response.eject(myInterceptor);
```
* update src/index.ts
```js
import { client } from 'client/client.gen';
async function myNewInterceptor(response) {
// do something
return response;
}
// update by ID
client.interceptors.response.update(interceptorId, myNewInterceptor);
// update by reference
client.interceptors.response.update(myInterceptor, myNewInterceptor);
```
## Auth [Section titled “Auth”](#auth) The SDKs include auth mechanisms for every endpoint. You will want to configure the `auth` field to pass the right token for each request. The `auth` field can be a string or a function returning a string representing the token. The returned value will be attached only to requests that require auth. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
auth: () => '',
baseUrl: 'https://example.com',
});
```
If you’re not using SDKs or generating auth, using interceptors is a common approach to configuring auth for each request. src/index.ts
```js
import { client } from 'client/client.gen';
client.interceptors.request.use((request, options) => {
request.headers.set('Authorization', 'Bearer ');
return request;
});
```
## Build URL [Section titled “Build URL”](#build-url) If you need to access the compiled URL, you can use the `buildUrl()` method. It’s loosely typed by default to accept almost any value; in practice, you will want to pass a type hint. src/index.ts
```ts
type FooData = {
path: {
fooId: number;
};
query?: {
bar?: string;
};
url: '/foo/{fooId}';
};
const url = client.buildUrl({
path: {
fooId: 1,
},
query: {
bar: 'baz',
},
url: '/foo/{fooId}',
});
console.log(url); // prints '/foo/1?bar=baz'
```
## Custom Instance [Section titled “Custom Instance”](#custom-instance) You can provide a custom `fetch` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
fetch: () => {
/* custom `fetch` method */
},
});
```
You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be. ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/client-fetch/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Got client
> Got client for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/586) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 3](https://github.com/hey-api/openapi-ts/issues/586) ### About [Section titled “About”](#about) [Got](https://github.com/sindresorhus/got) is a human-friendly and powerful HTTP request library for Node.js.
# Ky v1 Client
> Generate a type-safe Ky v1 client from OpenAPI with the Ky client for openapi-ts. Fully compatible with validators, transformers, and all core features.
### About [Section titled “About”](#about) [Ky](https://github.com/sindresorhus/ky) is a tiny and elegant JavaScript HTTP client based on the Fetch API. The Ky client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ### Collaborators [Section titled “Collaborators”](#collaborators) * [ Sebastiaan Wouters](https://github.com/SebastiaanWouters) ## Features [Section titled “Features”](#features) * seamless integration with `@hey-api/openapi-ts` ecosystem * type-safe response data and errors * response data validation and transformation * access to the original request and response * granular request and response customization options * minimal learning curve thanks to extending the underlying technology * support bundling inside the generated output ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@hey-api/client-ky` to your plugins and you’ll be ready to generate client artifacts. 🎉 * config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: ['@hey-api/client-ky'],
};
```
* cli
```sh
npx @hey-api/openapi-ts \
-i hey-api/backend \
-o src/client \
-c @hey-api/client-ky
```
## Configuration [Section titled “Configuration”](#configuration) The Ky client is built as a thin wrapper on top of Ky, extending its functionality to work with Hey API. If you’re already familiar with Ky, configuring your client will feel like working directly with Ky. When we installed the client above, it created a [`client.gen.ts`](https://heyapi.dev/docs/openapi/typescript/output#client) file. You will most likely want to configure the exported `client` instance. There are two ways to do that. ### `setConfig()` [Section titled “setConfig()”](#setconfig) This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Ky configuration option to `setConfig()`, and even your own [`ky`](#custom-instance) instance. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
baseUrl: 'https://example.com',
});
```
The disadvantage of this approach is that your code may call the `client` instance before it’s configured for the first time. Depending on your use case, you might need to use the second approach. ### Runtime API [Section titled “Runtime API”](#runtime-api) Since `client.gen.ts` is a generated file, we can’t directly modify it. Instead, we can tell our configuration to use a custom file implementing the Runtime API. We do that by specifying the `runtimeConfigPath` option. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
name: '@hey-api/client-ky',
runtimeConfigPath: './src/hey-api.ts',
},
],
};
```
In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values. src/hey-api.ts
```ts
import type { CreateClientConfig } from './client/client.gen';
export const createClientConfig: CreateClientConfig = (config) => ({
...config,
baseUrl: 'https://example.com',
});
```
With this approach, `client.gen.ts` will call `createClientConfig()` before initializing the `client` instance. If needed, you can still use `setConfig()` to update the client configuration later. ### `createClient()` [Section titled “createClient()”](#createclient) You can also create your own client instance. You can use it to manually send requests or point it to a different domain. src/index.ts
```js
import { createClient } from './client/client';
const myClient = createClient({
baseUrl: 'https://example.com',
});
```
You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`. src/index.ts
```js
const response = await getFoo({
client: myClient,
});
```
### SDKs [Section titled “SDKs”](#sdks) Alternatively, you can pass the client configuration options to each SDK function. This is useful if you don’t want to create a client instance for one-off use cases. src/index.ts
```js
const response = await getFoo({
baseUrl: 'https://example.com', // <-- override default configuration
});
```
## Interceptors [Section titled “Interceptors”](#interceptors) Interceptors (middleware) can be used to modify requests before they’re sent or responses before they’re returned to your application. They can be added with `use`, removed with `eject`, and updated wth `update`. The `use` and `update` methods will return the ID of the interceptor for use with `eject` and `update`. Ky does not have the interceptor functionality, so we implement our own. ### Example: Request interceptor [Section titled “Example: Request interceptor”](#example-request-interceptor) * use src/index.ts
```js
import { client } from 'client/client.gen';
async function myInterceptor(request) {
// do something
return request;
}
interceptorId = client.interceptors.request.use(myInterceptor);
```
* eject src/index.ts
```js
import { client } from 'client/client.gen';
// eject by ID
client.interceptors.request.eject(interceptorId);
// eject by reference
client.interceptors.request.eject(myInterceptor);
```
* update src/index.ts
```js
import { client } from 'client/client.gen';
async function myNewInterceptor(request) {
// do something
return request;
}
// update by ID
client.interceptors.request.update(interceptorId, myNewInterceptor);
// update by reference
client.interceptors.request.update(myInterceptor, myNewInterceptor);
```
### Example: Response interceptor [Section titled “Example: Response interceptor”](#example-response-interceptor) * use src/index.ts
```js
import { client } from 'client/client.gen';
async function myInterceptor(response) {
// do something
return response;
}
interceptorId = client.interceptors.response.use(myInterceptor);
```
* eject src/index.ts
```js
import { client } from 'client/client.gen';
// eject by ID
client.interceptors.response.eject(interceptorId);
// eject by reference
client.interceptors.response.eject(myInterceptor);
```
* update src/index.ts
```js
import { client } from 'client/client.gen';
async function myNewInterceptor(response) {
// do something
return response;
}
// update by ID
client.interceptors.response.update(interceptorId, myNewInterceptor);
// update by reference
client.interceptors.response.update(myInterceptor, myNewInterceptor);
```
## Auth [Section titled “Auth”](#auth) The SDKs include auth mechanisms for every endpoint. You will want to configure the `auth` field to pass the right token for each request. The `auth` field can be a string or a function returning a string representing the token. The returned value will be attached only to requests that require auth. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
auth: () => '',
baseUrl: 'https://example.com',
});
```
If you’re not using SDKs or generating auth, using interceptors is a common approach to configuring auth for each request. src/index.ts
```js
import { client } from 'client/client.gen';
client.interceptors.request.use((request, options) => {
request.headers.set('Authorization', 'Bearer ');
return request;
});
```
## Build URL [Section titled “Build URL”](#build-url) If you need to access the compiled URL, you can use the `buildUrl()` method. It’s loosely typed by default to accept almost any value; in practice, you will want to pass a type hint. src/index.ts
```ts
type FooData = {
path: {
fooId: number;
};
query?: {
bar?: string;
};
url: '/foo/{fooId}';
};
const url = client.buildUrl({
path: {
fooId: 1,
},
query: {
bar: 'baz',
},
url: '/foo/{fooId}',
});
console.log(url); // prints '/foo/1?bar=baz'
```
## Custom Instance [Section titled “Custom Instance”](#custom-instance) You can provide a custom `ky` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
ky: ky.create({
/* custom `ky` instance */
}),
});
```
You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be. ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/client-ky/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Next.js Client
> Generate a type-safe Next.js client from OpenAPI with the Next.js client for openapi-ts. Fully compatible with validators, transformers, and all core features.
### About [Section titled “About”](#about) [Next.js](https://nextjs.org) is the React framework for the web. Used by some of the world’s largest companies, Next.js enables you to create high-quality web applications with the power of React components. The Next.js client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ## Features [Section titled “Features”](#features) * seamless integration with `@hey-api/openapi-ts` ecosystem * type-safe response data and errors * response data validation and transformation * access to the original request and response * granular request and response customization options * minimal learning curve thanks to extending the underlying technology * support bundling inside the generated output ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@hey-api/client-next` to your plugins and you’ll be ready to generate client artifacts. 🎉 * config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: ['@hey-api/client-next'],
};
```
* cli
```sh
npx @hey-api/openapi-ts \
-i hey-api/backend \
-o src/client \
-c @hey-api/client-next
```
## Configuration [Section titled “Configuration”](#configuration) The Next.js client is built as a thin wrapper on top of [fetch](https://nextjs.org/docs/app/api-reference/functions/fetch), extending its functionality to work with Hey API. If you’re already familiar with Fetch, configuring your client will feel like working directly with Fetch API. When we installed the client above, it created a [`client.gen.ts`](https://heyapi.dev/docs/openapi/typescript/output#client) file. You will most likely want to configure the exported `client` instance. There are two ways to do that. ### Runtime API [Section titled “Runtime API”](#runtime-api) Since `client.gen.ts` is a generated file, we can’t directly modify it. Instead, we can tell our configuration to use a custom file implementing the Runtime API. We do that by specifying the `runtimeConfigPath` option. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
name: '@hey-api/client-next',
runtimeConfigPath: './src/hey-api.ts',
},
],
};
```
In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values. src/hey-api.ts
```ts
import type { CreateClientConfig } from './client/client.gen';
export const createClientConfig: CreateClientConfig = (config) => ({
...config,
baseUrl: 'https://example.com',
});
```
With this approach, `client.gen.ts` will call `createClientConfig()` before initializing the `client` instance. This is the recommended approach because it guarantees the client will be initialized in both server and client environment. If needed, you can still use `setConfig()` to update the client configuration later. ### `setConfig()` [Section titled “setConfig()”](#setconfig) This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Fetch API configuration option to `setConfig()`, and even your own [Fetch](#custom-instance) implementation. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
baseUrl: 'https://example.com',
});
```
The disadvantage of this approach is that your code may call the `client` instance before it’s configured for the first time. Depending on your use case, this might be an acceptable trade-off. However, our Next.js users usually want to use the first approach. ### `createClient()` [Section titled “createClient()”](#createclient) You can also create your own client instance. You can use it to manually send requests or point it to a different domain. src/index.ts
```js
import { createClient } from './client/client';
const myClient = createClient({
baseUrl: 'https://example.com',
});
```
You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`. src/index.ts
```js
const response = await getFoo({
client: myClient,
});
```
### SDKs [Section titled “SDKs”](#sdks) Alternatively, you can pass the client configuration options to each SDK function. This is useful if you don’t want to create a client instance for one-off use cases. src/index.ts
```js
const response = await getFoo({
baseUrl: 'https://example.com', // <-- override default configuration
});
```
## Interceptors [Section titled “Interceptors”](#interceptors) Interceptors (middleware) can be used to modify requests before they’re sent or responses before they’re returned to your application. They can be added with `use`, removed with `eject`, and updated wth `update`. The `use` and `update` methods will return the ID of the interceptor for use with `eject` and `update`. Fetch API does not have the interceptor functionality, so we implement our own. ### Example: Request interceptor [Section titled “Example: Request interceptor”](#example-request-interceptor) * use src/index.ts
```js
import { client } from 'client/client.gen';
async function myInterceptor(request) {
// do something
return request;
}
interceptorId = client.interceptors.request.use(myInterceptor);
```
* eject src/index.ts
```js
import { client } from 'client/client.gen';
// eject by ID
client.interceptors.request.eject(interceptorId);
// eject by reference
client.interceptors.request.eject(myInterceptor);
```
* update src/index.ts
```js
import { client } from 'client/client.gen';
async function myNewInterceptor(request) {
// do something
return request;
}
// update by ID
client.interceptors.request.update(interceptorId, myNewInterceptor);
// update by reference
client.interceptors.request.update(myInterceptor, myNewInterceptor);
```
### Example: Response interceptor [Section titled “Example: Response interceptor”](#example-response-interceptor) * use src/index.ts
```js
import { client } from 'client/client.gen';
async function myInterceptor(response) {
// do something
return response;
}
interceptorId = client.interceptors.response.use(myInterceptor);
```
* eject src/index.ts
```js
import { client } from 'client/client.gen';
// eject by ID
client.interceptors.response.eject(interceptorId);
// eject by reference
client.interceptors.response.eject(myInterceptor);
```
* update src/index.ts
```js
import { client } from 'client/client.gen';
async function myNewInterceptor(response) {
// do something
return response;
}
// update by ID
client.interceptors.response.update(interceptorId, myNewInterceptor);
// update by reference
client.interceptors.response.update(myInterceptor, myNewInterceptor);
```
## Auth [Section titled “Auth”](#auth) The SDKs include auth mechanisms for every endpoint. You will want to configure the `auth` field to pass the right token for each request. The `auth` field can be a string or a function returning a string representing the token. The returned value will be attached only to requests that require auth. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
auth: () => '',
baseUrl: 'https://example.com',
});
```
If you’re not using SDKs or generating auth, using interceptors is a common approach to configuring auth for each request. src/index.ts
```js
import { client } from 'client/client.gen';
client.interceptors.request.use((options) => {
options.headers.set('Authorization', 'Bearer ');
});
```
## Build URL [Section titled “Build URL”](#build-url) If you need to access the compiled URL, you can use the `buildUrl()` method. It’s loosely typed by default to accept almost any value; in practice, you will want to pass a type hint. src/index.ts
```ts
type FooData = {
path: {
fooId: number;
};
query?: {
bar?: string;
};
url: '/foo/{fooId}';
};
const url = client.buildUrl({
path: {
fooId: 1,
},
query: {
bar: 'baz',
},
url: '/foo/{fooId}',
});
console.log(url); // prints '/foo/1?bar=baz'
```
## Custom Instance [Section titled “Custom Instance”](#custom-instance) You can provide a custom `fetch` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
fetch: () => {
/* custom `fetch` method */
},
});
```
You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be. ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/client-next/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Nuxt v3 Client
> Generate a type-safe Nuxt v3 client from OpenAPI with the Nuxt client for openapi-ts. Fully compatible with validators, transformers, and all core features.
Beta [Leave feedback](https://github.com/hey-api/openapi-ts/issues) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) ### About [Section titled “About”](#about) [Nuxt](https://nuxt.com) is an open source framework that makes web development intuitive and powerful. The Nuxt client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ## Features [Section titled “Features”](#features) * Nuxt v3 support * seamless integration with `@hey-api/openapi-ts` ecosystem * type-safe response data and errors * response data validation and transformation * access to the original request and response * granular request and response customization options * minimal learning curve thanks to extending the underlying technology * support bundling inside the generated output ## Installation [Section titled “Installation”](#installation) Start by adding `@hey-api/nuxt` to your dependencies. * npm
```sh
npm install @hey-api/nuxt
```
* pnpm
```sh
pnpm add @hey-api/nuxt
```
* yarn
```sh
yarn add @hey-api/nuxt
```
* bun
```sh
bun add @hey-api/nuxt
```
In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@hey-api/client-nuxt` to your plugins and you’ll be ready to generate client artifacts. 🎉 * config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: ['@hey-api/client-nuxt'],
};
```
* cli
```sh
npx @hey-api/openapi-ts \
-i hey-api/backend \
-o src/client \
-c @hey-api/client-nuxt
```
## Configuration [Section titled “Configuration”](#configuration) The Nuxt client is built as a thin wrapper on top of Nuxt, extending its functionality to work with Hey API. If you’re already familiar with Nuxt, configuring your client will feel like working directly with Nuxt. When we installed the client above, it created a [`client.gen.ts`](https://heyapi.dev/docs/openapi/typescript/output#client) file. You will most likely want to configure the exported `client` instance. There are two ways to do that. ### `setConfig()` [Section titled “setConfig()”](#setconfig) This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Nuxt configuration option to `setConfig()`, and even your own [`$fetch`](#custom-instance) implementation. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
baseURL: 'https://example.com',
});
```
The disadvantage of this approach is that your code may call the `client` instance before it’s configured for the first time. Depending on your use case, you might need to use the second approach. ### Runtime API [Section titled “Runtime API”](#runtime-api) Since `client.gen.ts` is a generated file, we can’t directly modify it. Instead, we can tell our configuration to use a custom file implementing the Runtime API. We do that by specifying the `runtimeConfigPath` option. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
name: '@hey-api/client-nuxt',
runtimeConfigPath: './src/hey-api.ts',
},
],
};
```
In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values. src/hey-api.ts
```ts
import type { CreateClientConfig } from './client/client.gen';
export const createClientConfig: CreateClientConfig = (config) => ({
...config,
baseURL: 'https://example.com',
});
```
With this approach, `client.gen.ts` will call `createClientConfig()` before initializing the `client` instance. If needed, you can still use `setConfig()` to update the client configuration later. ### `createClient()` [Section titled “createClient()”](#createclient) You can also create your own client instance. You can use it to manually send requests or point it to a different domain. src/index.ts
```js
import { createClient } from './client/client';
const myClient = createClient({
baseURL: 'https://example.com',
});
```
You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`. src/index.ts
```js
const response = await getFoo({
client: myClient,
});
```
### SDKs [Section titled “SDKs”](#sdks) Alternatively, you can pass the client configuration options to each SDK function. This is useful if you don’t want to create a client instance for one-off use cases. src/index.ts
```js
const response = await getFoo({
baseURL: 'https://example.com', // <-- override default configuration
});
```
## Interceptors [Section titled “Interceptors”](#interceptors) Interceptors (middleware) can be used to modify requests before they’re sent or responses before they’re returned to your application. Nuxt provides interceptors through ofetch, please refer to their documentation on [$fetch](https://nuxt.com/docs/api/utils/dollarfetch). You can pass any Nuxt/ofetch arguments to the client instance. src/index.ts
```js
import { client } from 'client/client.gen';
const result = await client.get({
composable: '$fetch',
onRequest: (context) => {
// do something
},
url: '/foo',
});
```
## Auth [Section titled “Auth”](#auth) The SDKs include auth mechanisms for every endpoint. You will want to configure the `auth` field to pass the right token for each request. The `auth` field can be a string or a function returning a string representing the token. The returned value will be attached only to requests that require auth. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
auth: () => '',
baseURL: 'https://example.com',
});
```
If you’re not using SDKs or generating auth, using interceptors is a common approach to configuring auth for each request. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
onRequest: ({ options }) => {
options.headers.set('Authorization', 'Bearer ');
},
});
```
## Build URL [Section titled “Build URL”](#build-url) If you need to access the compiled URL, you can use the `buildUrl()` method. It’s loosely typed by default to accept almost any value; in practice, you will want to pass a type hint. src/index.ts
```ts
type FooData = {
path: {
fooId: number;
};
query?: {
bar?: string;
};
url: '/foo/{fooId}';
};
const url = client.buildUrl({
path: {
fooId: 1,
},
query: {
bar: 'baz',
},
url: '/foo/{fooId}',
});
console.log(url); // prints '/foo/1?bar=baz'
```
## Custom Instance [Section titled “Custom Instance”](#custom-instance) You can provide a custom `$fetch` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
$fetch: () => {
/* custom `$fetch` method */
},
});
```
You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be. ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# OFetch Client
> Generate a type-safe ofetch client from OpenAPI with the ofetch client for openapi-ts. Fully compatible with validators, transformers, and all core features.
### About [Section titled “About”](#about) [`ofetch`](https://github.com/unjs/ofetch) is a better Fetch API that adds useful defaults and features such as automatic response parsing, request/response hooks, and it works in Node, browser, and workers. The `ofetch` client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ### Collaborators [Section titled “Collaborators”](#collaborators) * [ Dmitriy Brolnickij](https://github.com/brolnickij) ## Features [Section titled “Features”](#features) * seamless integration with `@hey-api/openapi-ts` ecosystem * type-safe response data and errors * response data validation and transformation * access to the original request and response * granular request and response customization options * minimal learning curve thanks to extending the underlying technology * support bundling inside the generated output ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@hey-api/client-ofetch` to your plugins and you’ll be ready to generate client artifacts. 🎉 * config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: ['@hey-api/client-ofetch'],
};
```
* cli
```sh
npx @hey-api/openapi-ts \
-i hey-api/backend \
-o src/client \
-c @hey-api/client-ofetch
```
## Configuration [Section titled “Configuration”](#configuration) The `ofetch` client is built as a thin wrapper on top of `ofetch`, extending its functionality to work with Hey API. If you’re already familiar with `ofetch`, configuring your client will feel like working directly with `ofetch`. When we installed the client above, it created a [`client.gen.ts`](https://heyapi.dev/docs/openapi/typescript/output#client) file. You will most likely want to configure the exported `client` instance. There are two ways to do that. ### `setConfig()` [Section titled “setConfig()”](#setconfig) This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any `ofetch` configuration option to `setConfig()`, and even your own [`ofetch`](#custom-instance) instance. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
baseUrl: 'https://example.com',
});
```
The disadvantage of this approach is that your code may call the `client` instance before it’s configured for the first time. Depending on your use case, you might need to use the second approach. ### Runtime API [Section titled “Runtime API”](#runtime-api) Since `client.gen.ts` is a generated file, we can’t directly modify it. Instead, we can tell our configuration to use a custom file implementing the Runtime API. We do that by specifying the `runtimeConfigPath` option. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
name: '@hey-api/client-ofetch',
runtimeConfigPath: './src/hey-api.ts',
},
],
};
```
In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values. src/hey-api.ts
```ts
import type { CreateClientConfig } from './client/client.gen';
export const createClientConfig: CreateClientConfig = (config) => ({
...config,
baseUrl: 'https://example.com',
});
```
With this approach, `client.gen.ts` will call `createClientConfig()` before initializing the `client` instance. If needed, you can still use `setConfig()` to update the client configuration later. ### `createClient()` [Section titled “createClient()”](#createclient) You can also create your own client instance. You can use it to manually send requests or point it to a different domain. src/index.ts
```js
import { createClient } from './client/client';
const myClient = createClient({
baseUrl: 'https://example.com',
});
```
You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`. src/index.ts
```js
const response = await getFoo({
client: myClient,
});
```
### SDKs [Section titled “SDKs”](#sdks) Alternatively, you can pass the client configuration options to each SDK function. This is useful if you don’t want to create a client instance for one-off use cases. src/index.ts
```js
const response = await getFoo({
baseUrl: 'https://example.com', // <-- override default configuration
});
```
## Interceptors [Section titled “Interceptors”](#interceptors) Interceptors (middleware) can be used to modify requests before they’re sent or responses before they’re returned to your application. The `ofetch` client supports two complementary options: * built-in Hey API interceptors exposed via `client.interceptors` * native `ofetch` hooks passed through config (e.g., `onRequest`) ### Example: Request interceptor [Section titled “Example: Request interceptor”](#example-request-interceptor) * use src/index.ts
```js
import { client } from 'client/client.gen';
async function myInterceptor(request) {
// do something
return request;
}
interceptorId = client.interceptors.request.use(myInterceptor);
```
* eject src/index.ts
```js
import { client } from 'client/client.gen';
// eject by ID
client.interceptors.request.eject(interceptorId);
// eject by reference
client.interceptors.request.eject(myInterceptor);
```
* update src/index.ts
```js
import { client } from 'client/client.gen';
async function myNewInterceptor(request) {
// do something
return request;
}
// update by ID
client.interceptors.request.update(interceptorId, myNewInterceptor);
// update by reference
client.interceptors.request.update(myInterceptor, myNewInterceptor);
```
### Example: Response interceptor [Section titled “Example: Response interceptor”](#example-response-interceptor) * use src/index.ts
```js
import { client } from 'client/client.gen';
async function myInterceptor(response) {
// do something
return response;
}
interceptorId = client.interceptors.response.use(myInterceptor);
```
* eject src/index.ts
```js
import { client } from 'client/client.gen';
// eject by ID
client.interceptors.response.eject(interceptorId);
// eject by reference
client.interceptors.response.eject(myInterceptor);
```
* update src/index.ts
```js
import { client } from 'client/client.gen';
async function myNewInterceptor(response) {
// do something
return response;
}
// update by ID
client.interceptors.response.update(interceptorId, myNewInterceptor);
// update by reference
client.interceptors.response.update(myInterceptor, myNewInterceptor);
```
### Example: `ofetch` hooks [Section titled “Example: ofetch hooks”](#example-ofetch-hooks) src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
onRequest: ({ options }) => {
// mutate ofetch options (headers, query, etc.)
},
onResponse: ({ response }) => {
// inspect/transform the raw Response
},
onRequestError: (ctx) => {
// handle request errors
},
onResponseError: (ctx) => {
// handle response errors
},
});
```
## Auth [Section titled “Auth”](#auth) The SDKs include auth mechanisms for every endpoint. You will want to configure the `auth` field to pass the right token for each request. The `auth` field can be a string or a function returning a string representing the token. The returned value will be attached only to requests that require auth. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
auth: () => '',
baseUrl: 'https://example.com',
});
```
If you’re not using SDKs or generating auth, using interceptors is a common approach to configuring auth for each request. src/index.ts
```js
import { client } from 'client/client.gen';
client.interceptors.request.use((request, options) => {
request.headers.set('Authorization', 'Bearer ');
return request;
});
```
You can also use the `ofetch` hooks. src/index.ts
```js
import { client } from 'client/client.gen';
client.setConfig({
onRequest: ({ options }) => {
options.headers.set('Authorization', 'Bearer ');
},
});
```
## Build URL [Section titled “Build URL”](#build-url) If you need to access the compiled URL, you can use the `buildUrl()` method. It’s loosely typed by default to accept almost any value; in practice, you will want to pass a type hint. src/index.ts
```ts
type FooData = {
path: {
fooId: number;
};
query?: {
bar?: string;
};
url: '/foo/{fooId}';
};
const url = client.buildUrl({
path: {
fooId: 1,
},
query: {
bar: 'baz',
},
url: '/foo/{fooId}',
});
console.log(url); // prints '/foo/1?bar=baz'
```
## Custom Instance [Section titled “Custom Instance”](#custom-instance) You can provide a custom `ofetch` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether. src/index.ts
```js
import { ofetch } from 'ofetch';
import { client } from 'client/client.gen';
const customOFetchInstance = ofetch.create({
onRequest: ({ options }) => {
// customize request
},
onResponse: ({ response }) => {
// customize response
},
});
client.setConfig({
ofetch: customOFetchInstance,
});
```
You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be. ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/client-ofetch/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Contributing
> Learn how to contribute to Hey API.
## Foreword [Section titled “Foreword”](#foreword) Hey API is building an OpenAPI to TypeScript code generator ecosystem. It’s trusted by thousands of companies – from YC startups to Fortune 500 enterprises – and powers products used by millions worldwide. We welcome contributors of all backgrounds and experience levels. Whether you’re fixing a typo or building a new feature, your input matters. If you need guidance, help with technical writing, or want to bring a feature idea to life, we’re here to support you. ## First Steps [Section titled “First Steps”](#first-steps) There are many ways to contribute to Hey API. Most of them don’t involve writing any code! * **Read the documentation**. Start with the [Get Started](https://heyapi.dev/docs/openapi/typescript/get-started) guide. If you find anything broken or confusing, you can suggest improvements by clicking “Edit” at the bottom of any page. * **Browse open issues**. Help others by providing workarounds, asking for clarification, triaging, or suggesting labels on [open issues](https://github.com/hey-api/openapi-ts/issues). If you see something you would like to work on, consider opening a pull request. * **Participate in discussions**. Ask or [answer questions](https://github.com/orgs/hey-api/discussions), provide feedback, or suggest new ideas. Every idea is welcome, no matter how big or small. * **Engage on social media**. Help others discover Hey API by engaging with our posts on [LinkedIn](https://linkedin.com/company/heyapi), [Bluesky](https://bsky.app/profile/heyapi.dev), or [X](https://x.com/mrlubos). Share your experiences with Hey API on Reddit, Slack, or in your own communities and group chats. * **Create a new issue**. If you can’t find a solution, [open an issue](https://github.com/hey-api/openapi-ts/issues). The issue template will guide you through the process. * **Open a pull request**. If you find an issue you would like to fix, open a pull request. If you need help, tag [`@mrlubos`](https://github.com/mrlubos) on GitHub, provide enough relevant information, and we will do our best to assist you. These are some of the best ways not only to contribute to Hey API, but also to learn, connect with others, and share ideas. ## Pull Requests [Section titled “Pull Requests”](#pull-requests) Ready to write some code? We have dedicated guides to help you [build](https://heyapi.dev/docs/openapi/typescript/community/contributing/building), [develop](https://heyapi.dev/docs/openapi/typescript/community/contributing/developing), and [test](https://heyapi.dev/docs/openapi/typescript/community/contributing/testing) your feature before it’s released. We are excited to see what you’ll contribute!
# Building
> Learn how to contribute to Hey API.
Caution This page is under construction. We appreciate your patience. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) You should have a working knowledge of [git](https://git-scm.com), [node](https://nodejs.org/en), and [pnpm](https://pnpm.io). ## Guidelines [Section titled “Guidelines”](#guidelines) Your [pull request](https://help.github.com/articles/using-pull-requests) must: * address a single issue or add a single item of functionality * contain a clean history of small, incremental, logically separate commits, with no merge commits * use clear commit messages * be possible to merge automatically ## Start `@hey-api/openapi-ts` [Section titled “Start @hey-api/openapi-ts”](#start-hey-apiopenapi-ts) Run `pnpm --filter @hey-api/openapi-ts dev`.
# Developing
> Learn how to contribute to Hey API.
Caution This page is under construction. We appreciate your patience. ## Working with Examples [Section titled “Working with Examples”](#working-with-examples) The `examples` folder contains various integration examples that demonstrate how to use `@hey-api/openapi-ts` with different frameworks and libraries. These examples are kept in sync with the codebase through automated checks. ### Generating Example Code [Section titled “Generating Example Code”](#generating-example-code) When you make changes to the core packages that affect code generation, you need to regenerate the client code in all examples:
```sh
pnpm examples:generate
```
This command will: * Find all examples with an `openapi-ts` script * Run the OpenAPI code generator for each example * Update the generated client code in each example ### Checking Example Code [Section titled “Checking Example Code”](#checking-example-code) Before committing changes, ensure that all generated example code is up-to-date:
```sh
pnpm examples:check
```
This command will: * Regenerate all example code * Check if any files were modified * Exit with an error if generated code is out of sync This check is also run automatically in CI to ensure examples stay in sync with the main codebase. ### Example Workflow [Section titled “Example Workflow”](#example-workflow) 1. Make changes to core packages 2. Build the packages: `pnpm build --filter="@hey-api/**"` 3. Regenerate examples: `pnpm examples:generate` 4. Commit all changes including the updated generated code 5. The CI will verify that examples are in sync ## Writing Changelogs [Section titled “Writing Changelogs”](#writing-changelogs) We use [Changesets](https://github.com/changesets/changesets) to manage releases and generate changelogs. When contributing changes, create a changeset to document your updates. ### Creating a Changeset [Section titled “Creating a Changeset”](#creating-a-changeset) Run the following command to create a new changeset:
```sh
pnpm changeset
```
This will prompt you to: 1. Select the packages that were changed 2. Choose the semver bump type (major, minor, or patch) 3. Write a summary of your changes ### Changeset Format [Section titled “Changeset Format”](#changeset-format) Changesets use the following format: example.changeset.md
```md
---
"@hey-api/openapi-ts": patch
---
**scope**: description of changes
```
**Scopes:** * `cli`, `parser`, `output`, `config`, `input`, `internal`, `build`, `error` → Core section * `plugin(name)` → Plugins section (e.g., `**plugin(zod)**:`, `**plugin(@hey-api/client-axios)**:`) * Any other scope → Other section **Breaking Changes:** * Use `**BREAKING**:` prefix in the description to mark breaking changes * For packages on v0.x (major version 0), minor bumps may include breaking changes. Use signal words like “removed”, “renamed”, or “changed signature” to indicate breaking changes. ### Examples [Section titled “Examples”](#examples) * Bug fix example.changeset.md
```md
---
"@hey-api/openapi-ts": patch
---
**parser**: fix explicit discriminator mapping
```
* New feature example.changeset.md
```md
---
"@hey-api/openapi-ts": minor
---
**plugin(zod)**: handle guid string format
```
* Breaking change example.changeset.md
```md
---
"@hey-api/openapi-ts": minor
---
**BREAKING**: removed deprecated `getClient()` function
```
* Plugin change example.changeset.md
```md
---
"@hey-api/openapi-ts": patch
---
**plugin(@hey-api/client-fetch)**: improve error handling
```
# Testing
> Learn how to contribute to Hey API.
Caution This page is under construction. We appreciate your patience.
# Spotlight
> Meet the people behind Hey API.
Meet the people behind Hey API. To join this list, please refer to the [contributing](https://heyapi.dev/docs/openapi/typescript/community/contributing) guide. ## Core Team [Section titled “Core Team”](#core-team) These people actively maintain Hey API. *  Lubos Hey API [](https://github.com/mrlubos) Do you want to join the core team? Send us a short [email](mailto:lubos@heyapi.dev?subject=Join%20Core%20Team) describing your interest in Hey API, any relevant experience, and what you’re hoping to work on. ## Hall of Fame [Section titled “Hall of Fame”](#hall-of-fame) These are the people with significant contributions to Hey API. A special thank you goes to [Ferdi Koomen](https://madebyferdi.com) for allowing us to use the original source code from OpenAPI TypeScript Codegen. None of this would’ve been possible without you! *  Ferdi Koomen OpenAPI TypeScript Codegen [](https://github.com/ferdikoomen) *  Nicolas Chaulet Made the Hey API fork [](https://github.com/nicolas-chaulet) *  Jordan Shatford Maintainer and Contributor [](https://github.com/jordanshatford) ## Contributors [Section titled “Contributors”](#contributors) The complete list of contributors to Hey API. * [Abdullah Alaqeel](https://github.com/aqeelat) * [Ahmed Rowaihi](https://github.com/ahmedrowaihi) * [Alessandro](https://github.com/ale18V) * [Alex Sagal](https://github.com/spikesagal) * [Alex Sarychev](https://github.com/Freddis) * [Alex Vukadinov](https://github.com/alexvuka1) * [Alex Yang](https://github.com/himself65) * [Alexander Horner](https://github.com/alexanderhorner) * [Alexander Skvortcov](https://github.com/askvortcov) * [Andrea](https://github.com/andreasciamanna) * [Andreas Adam](https://github.com/pixelmord) * [Ben Vincent](https://github.com/bvincent1) * [Björn Henriksson](https://github.com/bjornhenriksson) * [Bogdan](https://github.com/BogdanMaier) * [Brian Tarricone](https://github.com/kelnos) * [Bryon Larrance](https://github.com/beelarr) * [Carl Kittelberger](https://github.com/icedream) * [Changwan](https://github.com/WooWan) * [Chris Wiggins](https://github.com/chriswiggins) * [Daniel Roe](https://github.com/danielroe) * [Daschi](https://github.com/Daschi1) * [David Bieregger](https://github.com/BierDav) * [David Ovčačík](https://github.com/dovca) * [Dmitriy Brolnickij](https://github.com/brolnickij) * [Dmitry](https://github.com/codercms) * [Eirik Bøe](https://github.com/OptoCloud) * [Erikwski](https://github.com/erikwski) * [Finn Poppinga](https://github.com/fpoppinga) * [Flo Edelmann](https://github.com/FloEdelmann) * [Florian Lutze](https://github.com/flow96) * [Francesco Stefanini](https://github.com/frastefanini) * [Francisco García](https://github.com/goltra) * [George Smith](https://github.com/georgesmith46) * [Gergan Penkov](https://github.com/gergan) * [Hector Ayala](https://github.com/bombillazo) * [Hiram Chirino](https://github.com/chirino) * [Idan Ben Ami](https://github.com/idbenami) * [Inas Sirhan](https://github.com/inas-sirhan) * [Jan](https://github.com/JanST123) * [Jason Lee](https://github.com/LeeChSien) * [Jason Westover](https://github.com/j-westover) * [Jeff James](https://github.com/jsjames) * [Jianqi Pan](https://github.com/Jannchie) * [Jo](https://github.com/josh-hemphill) * [John Gozde](https://github.com/jgoz) * [Jordan Shatford](https://github.com/jordanshatford) * [Joshua](https://github.com/Joshua-hypt) * [Jostein Stuhaug](https://github.com/josstn) * [Juan Ibarra](https://github.com/j-ibarra) * [Julian Klumpers](https://github.com/julianklumpers) * [Karl Stoney](https://github.com/Stono) * [Keigo Ando](https://github.com/anchan828) * [Kenneth Apeland](https://github.com/kennidenni) * [Kit Langton](https://github.com/kitlangton) * [Landon Gavin](https://github.com/seriouslag) * [Laurin](https://github.com/lausek) * [Lee Lian Hoy](https://github.com/bakakaba) * [Leo Developer](https://github.com/Le0Developer) * [Linus Fischer](https://github.com/LeiCraft) * [Louis Duchemin](https://github.com/lsdch) * [Lubos](https://github.com/mrlubos) * [Lukas Podmelle](https://github.com/lukaspodmelle) * [Luke Rohde](https://github.com/thyming) * [Maarten Knijnenberg](https://github.com/mknijnenberg) * [Mads Hougesen](https://github.com/hougesen) * [Malcolm Kee](https://github.com/malcolm-kee) * [Marcel Richter](https://github.com/mrclrchtr) * [Marek Lukáš](https://github.com/tajnymag) * [Martín Fernández](https://github.com/bilby91) * [Matsu](https://github.com/Matsuuu) * [Matt Adam](https://github.com/matthewjamesadam) * [Maurici Abad Gutierrez](https://github.com/mauriciabad) * [Max Scopp](https://github.com/max-scopp) * [Maximilian Dewald](https://github.com/maxdewald) * [Michał Grezel](https://github.com/dracomithril) * [Michiel Lankamp](https://github.com/mlankamp) * [Mika Vilpas](https://github.com/mikavilpas) * [Miklos](https://github.com/jumika) * [Nacho García](https://github.com/nachogarcia) * [Nicolas Chaulet](https://github.com/nicolas-chaulet) * [Niels Mokkenstorm](https://github.com/nmokkenstorm) * [Nikita Perepelitsa](https://github.com/quartepie) * [Nimo Beeren](https://github.com/nimobeeren) * [Novak Antonijevic](https://github.com/NovakAnton) * [Ondřej Maxa](https://github.com/maxa-ondrej) * [Pascal Ernst](https://github.com/LinuCC) * [Peter Graugaard](https://github.com/pgraug) * [Philipp Katz](https://github.com/qqilihq) * [Phuc Tran](https://github.com/Glup3) * [Rico](https://github.com/btmnk) * [Roland Weiss](https://github.com/rolego) * [Roya](https://github.com/awdr74100) * [Ryo Yamada](https://github.com/Liooo) * [Salman Shaikh](https://github.com/slmnsh) * [Sebastiaan Wouters](https://github.com/SebastiaanWouters) * [Shinigami](https://github.com/Shinigami92) * [Simen Bekkhus](https://github.com/SimenB) * [Sipan Petrosyan](https://github.com/SipanP) * [Sjoerd Scheffer](https://github.com/ixnas) * [Spencer Sargent](https://github.com/sbs44) * [Stephen Zhou](https://github.com/hyoban) * [Stian Jensen](https://github.com/stianjensen) * [Sukka](https://github.com/SukkaW) * [SunwooLee](https://github.com/programsurf) * [Tom van de Velde](https://github.com/tomvdv) * [Vincent Olesen](https://github.com/volesen) * [Warren Seine](https://github.com/warrenseine) * [Yuri Mikhin](https://github.com/mikhin) * [a1mer](https://github.com/a1mersnow) * [carson](https://github.com/carson2222) * [chrg1001](https://github.com/chrg1001) * [johnny kim](https://github.com/johnny-mh) * [yyh](https://github.com/lyzno1) * [0xfurai](https://github.com/0xfurai) * [9M6](https://github.com/9M6) * [Ben-Pfirsich](https://github.com/Ben-Pfirsich) * [Copilot](https://github.com/Copilot) * [Daschi2](https://github.com/Daschi2) * [Mxwllas](https://github.com/Mxwllas) * [RndUsername](https://github.com/RndUsername) * [Schroedi](https://github.com/Schroedi) * [alexedme](https://github.com/alexedme) * [ben-pietsch](https://github.com/ben-pietsch) * [fml09](https://github.com/fml09) * [henry-encord](https://github.com/henry-encord) * [hunshcn](https://github.com/hunshcn) * [jcx0](https://github.com/jcx0) * [maxdew-envelio](https://github.com/maxdew-envelio) * [nnzhadow](https://github.com/nnzhadow) * [renoschubert](https://github.com/renoschubert) * [tpuric](https://github.com/tpuric) A sincere thank you for your contributions.
# Configuration
> Configure @hey-api/openapi-ts.
`@hey-api/openapi-ts` supports loading configuration from any file inside your project root folder supported by [jiti loader](https://github.com/unjs/c12?tab=readme-ov-file#-features). Below are the most common file formats. * openapi-ts.config.ts
```ts
import { defineConfig } from '@hey-api/openapi-ts';
export default defineConfig({
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
});
```
* openapi-ts.config.cjs
```js
/** @type {import('@hey-api/openapi-ts').UserConfig} */
module.exports = {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};
```
* openapi-ts.config.mjs
```js
/** @type {import('@hey-api/openapi-ts').UserConfig} */
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};
```
Alternatively, you can use `openapi-ts.config.js` and configure the export statement depending on your project setup. ## Input [Section titled “Input”](#input) You must provide an input so we can load your OpenAPI specification. The input can be a string path, URL, [API registry](https://heyapi.dev/docs/openapi/typescript/configuration/input#api-registry) shorthand, an object containing any of these, or an object representing an OpenAPI specification. Hey API supports all valid OpenAPI versions and file formats. You can learn more on the [Input](https://heyapi.dev/docs/openapi/typescript/configuration/input) page. * path openapi-ts.config.ts
```js
export default {
input: './path/to/openapi.json',
};
```
* url openapi-ts.config.ts
```js
export default {
input: 'https://get.heyapi.dev/hey-api/backend', // sign up at app.heyapi.dev
};
```
* registry openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
};
```
* object openapi-ts.config.ts
```js
export default {
input: {
path: 'hey-api/backend', // sign up at app.heyapi.dev
// ...other options
},
};
```
* spec openapi-ts.config.ts
```js
export default {
input: {
openapi: '3.1.1',
// ...rest of your spec
},
};
```
## Output [Section titled “Output”](#output) You must set the output so we know where to generate your files. It can be a path to the destination folder or an object containing the destination folder path and optional settings. You can learn more on the [Output](https://heyapi.dev/docs/openapi/typescript/configuration/output) page. * path
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};
```
* object
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
// ...other options
},
};
```
## Parser [Section titled “Parser”](#parser) We parse your input before making it available to plugins. Configuring the parser is optional, but it provides an ideal opportunity to modify or validate your input as needed. You can learn more on the [Parser](https://heyapi.dev/docs/openapi/typescript/configuration/parser) page. ## Plugins [Section titled “Plugins”](#plugins) Plugins are responsible for generating artifacts from your input. By default, Hey API will generate TypeScript interfaces and SDK from your OpenAPI specification. You can add, remove, or customize any of the plugins. In fact, we highly encourage you to do so! You can learn more on the [Output](https://heyapi.dev/docs/openapi/typescript/output) page. ## Advanced [Section titled “Advanced”](#advanced) More complex configuration scenarios can be handled by providing an array of inputs, outputs, or configurations. ### Multiple jobs [Section titled “Multiple jobs”](#multiple-jobs) Throughout this documentation, we generally reference single job configurations. However, you can easily run multiple jobs by providing an array of configuration objects. * config
```js
export default [
{
input: 'foo.yaml',
output: 'src/foo',
},
{
input: 'bar.yaml',
output: 'src/bar',
},
];
```
* example ### Job matrix [Section titled “Job matrix”](#job-matrix) Reusing configuration across multiple jobs is possible by defining a job matrix. You can create a job matrix by providing `input` and `output` arrays of matching length. * config
```js
export default {
input: ['foo.yaml', 'bar.yaml'],
output: ['src/foo', 'src/bar'],
};
```
* example ### Merging inputs [Section titled “Merging inputs”](#merging-inputs) You can merge inputs by defining multiple inputs and a single output. * config
```js
export default {
input: ['foo.yaml', 'bar.yaml'],
output: 'src/client',
};
```
* example ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/config/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Input
> Configure @hey-api/openapi-ts.
You must provide an input so we can load your OpenAPI specification. ## Input [Section titled “Input”](#input) The input can be a string path, URL, [API registry](#api-registry), an object containing any of these, or an object representing an OpenAPI specification. Hey API supports all valid OpenAPI versions and file formats. * path openapi-ts.config.ts
```js
export default {
input: './path/to/openapi.json',
};
```
* url openapi-ts.config.ts
```js
export default {
input: 'https://get.heyapi.dev/hey-api/backend', // sign up at app.heyapi.dev
};
```
* registry openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
};
```
* object openapi-ts.config.ts
```js
export default {
input: {
path: 'hey-api/backend', // sign up at app.heyapi.dev
// ...other options
},
};
```
* spec openapi-ts.config.ts
```js
export default {
input: {
openapi: '3.1.1',
// ...rest of your spec
},
};
```
You can learn more about complex use cases in the [Advanced](https://heyapi.dev/docs/openapi/typescript/configuration#advanced) section. ### Request options [Section titled “Request options”](#request-options) You can pass any valid Fetch API [options](https://developer.mozilla.org/docs/Web/API/RequestInit) to the request for fetching your specification. This is useful if your file is behind auth for example. openapi-ts.config.ts
```js
export default {
input: {
path: 'https://secret.com/protected-spec',
fetch: {
headers: {
Authorization: 'Bearer xxx',
},
},
},
};
```
## API Registry [Section titled “API Registry”](#api-registry) You can store your specifications in an API registry to serve as a single source of truth. This helps prevent drift, improves discoverability, enables version tracking, and more. ### Hey API [Section titled “Hey API”](#hey-api) You can learn more about [Hey API Platform](https://app.heyapi.dev) on the [Integrations](https://heyapi.dev/docs/openapi/typescript/integrations) page. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
};
```
The `input` object lets you provide additional options to construct the correct URL. openapi-ts.config.ts
```js
export default {
input: {
path: 'hey-api/backend', // sign up at app.heyapi.dev
branch: 'main',
},
};
```
We also provide shorthands for other registries: ## Watch Mode [Section titled “Watch Mode”](#watch-mode) Caution Watch mode currently supports only remote files via URL. If your schema changes frequently, you may want to automatically regenerate the output during development. To watch your input file for changes, enable `input.watch` mode in your configuration or pass the `--watch` flag to the CLI. * config openapi-ts.config.ts
```js
export default {
input: {
path: 'hey-api/backend', // sign up at app.heyapi.dev
watch: true,
},
};
```
* cli
```sh
npx @hey-api/openapi-ts -i hey-api/backend -o src/client -w
```
## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Output
> Configure @hey-api/openapi-ts.
You must set the output so we know where to generate your files. ## Output [Section titled “Output”](#output) Output can be a path to the destination folder or an object containing the destination folder path and optional settings. * path
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};
```
* object
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
// ...other options
},
};
```
You can learn more about complex use cases in the [Advanced](https://heyapi.dev/docs/openapi/typescript/configuration#advanced) section. ## File [Section titled “File”](#file) Control how files are named and annotated in the generated output. ### File Name [Section titled “File Name”](#file-name) You can customize the naming and casing pattern for files using the `fileName` option. * default openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
fileName: '{{name}}',
path: 'src/client',
},
};
```
* snake\_case openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
fileName: {
case: 'snake_case',
},
path: 'src/client',
},
};
```
By default, we append every file name with a `.gen` suffix to highlight it’s automatically generated. You can customize or disable this suffix using the `fileName.suffix` option. * default openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
fileName: {
suffix: '.gen',
},
path: 'src/client',
},
};
```
* disabled openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
fileName: {
suffix: null,
},
path: 'src/client',
},
};
```
* custom openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
fileName: {
suffix: '.generated',
},
path: 'src/client',
},
};
```
### File Header [Section titled “File Header”](#file-header) The generated output includes a notice in every file warning that any modifications will be lost when the files are regenerated. You can customize or disable this notice using the `header` option. * example index.gen.ts
```js
/* eslint-disable */
// This file is auto-generated by @hey-api/openapi-ts
/** ... */
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
header: (ctx) => [
'/* eslint-disable */',
...ctx.defaultValue,
],
path: 'src/client',
},
};
```
## Module [Section titled “Module”](#module) Control how module specifiers are generated in the output. ### Module Extension [Section titled “Module Extension”](#module-extension) Set `module.extension` to define the file extension used in import specifiers. This is useful when targeting environments that require fully specified imports (e.g., Node ESM or certain bundlers). * example index.gen.ts
```js
import foo from './foo.js';
import bar from './bar.js';
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
module: {
extension: '.js',
},
path: 'src/client',
},
};
```
### Module Path [Section titled “Module Path”](#module-path) Use `module.resolve` for full control over how module specifiers are generated. This lets you override specific modules or redirect them to custom locations (e.g., CDNs or internal aliases). * example index.gen.ts
```js
import * as z from 'https://esm.sh/zod';
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
module: {
resolve(path) {
if (path === 'zod') {
return 'https://esm.sh/zod';
}
},
},
path: 'src/client',
},
};
```
## Source [Section titled “Source”](#source) Source is a copy of the input specification used to generate your output. It can be used to power documentation tools or to persist a stable snapshot alongside your generated files. Enabling the `source` option with `true` creates a `source.json` file in your output folder. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
source: true,
},
};
```
You can customize the file name and location using `fileName` and `path`. For example, this configuration will create an `openapi.json` file inside `src/client/source` directory. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
source: {
fileName: 'openapi',
path: './source',
},
},
};
```
To use the source without writing it to disk, you can provide a `callback` function. This is useful for logging or integrating with external systems. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
source: {
callback: (source) => console.log(source),
path: null,
},
},
};
```
## Post Process [Section titled “Post Process”](#post-process) Post-processing allows you to run commands on the generated output folder after files are written. This is typically used to run formatters, linters, or other cleanup tools. Commands are executed in order, and each command receives the output path via the `path` placeholder. ### Presets [Section titled “Presets”](#presets) You can use built-in presets for common tools: * biome:check openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['biome:check'],
},
};
```
* biome:format openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['biome:format'],
},
};
```
* biome:lint openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['biome:lint'],
},
};
```
* eslint openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['eslint'],
},
};
```
* oxfmt openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['oxfmt'],
},
};
```
* oxlint openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['oxlint'],
},
};
```
* prettier openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['prettier'],
},
};
```
### Custom [Section titled “Custom”](#custom) You can also provide custom post processors: openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: [
{
command: 'dprint',
args: ['fmt', '{{path}}'],
},
],
},
};
```
You can skip processing by adding the output path to the tool’s ignore file (for example `.eslintignore` or `.prettierignore`). ## Name Conflicts [Section titled “Name Conflicts”](#name-conflicts) As your project grows, the chances of name conflicts increase. We use a simple conflict resolver that appends numeric suffixes to duplicate identifiers. If you prefer a different strategy, you can provide your own `nameConflictResolver` function. * config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
nameConflictResolver({ attempt, baseName }) {
return attempt === 0 ? baseName : `${baseName}_N${attempt + 1}`;
},
path: 'src/client',
},
};
```
* example index.gen.ts
```ts
export type ChatCompletion = string;
export type ChatCompletion_N2 = number;
```
## TSConfig Path [Section titled “TSConfig Path”](#tsconfig-path) We use the [TSConfig file](https://www.typescriptlang.org/tsconfig/) to generate output matching your project’s settings. By default, we attempt to find a TSConfig file starting from the location of the `@hey-api/openapi-ts` configuration file and traversing up. * default openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
tsConfigPath: undefined,
},
};
```
* custom openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
tsConfigPath: './config/tsconfig.custom.json',
},
};
```
* disabled openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
tsConfigPath: null,
},
};
```
## Custom Files [Section titled “Custom Files”](#custom-files) By default, you can’t keep custom files in the `path` folder because it’s emptied on every run. If you’re sure you need to disable this behavior, set `clean` to `false`. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
clean: false,
path: 'src/client',
},
};
```
Caution Setting `clean` to `false` may result in broken output. Ensure you typecheck your code. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Parser
> Configure @hey-api/openapi-ts.
We parse your input before making it available to plugins. Configuring the parser is optional, but it provides an ideal opportunity to modify or validate your input as needed. ## Patch [Section titled “Patch”](#patch) Sometimes you need to modify raw input before it’s processed further. A common use case is fixing an invalid specification or adding a missing field. For this reason, custom patches are applied before any parsing takes place. You can add custom patches with `patch`. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
patch: {
schemas: {
Foo: (schema) => {
// convert date-time format to timestamp
delete schema.properties.updatedAt.format;
schema.properties.updatedAt.type = 'number';
},
Bar: (schema) => {
// add missing property
schema.properties.meta = {
additionalProperties: true,
type: 'object',
};
schema.required = ['meta'];
},
Baz: (schema) => {
// remove property
delete schema.properties.internalField;
},
},
},
},
};
```
## Validate [Section titled “Validate”](#validate) Caution The validator feature is very limited. You can help improve it by submitting more [use cases](https://github.com/hey-api/openapi-ts/issues/1970#issuecomment-2933189789). If you don’t control or trust your input, you might want to validate it. Any detected errors in your input will exit `@hey-api/openapi-ts` and no plugins will be executed. To validate your input, set `validate_EXPERIMENTAL` to `true`. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
validate_EXPERIMENTAL: true,
},
};
```
## Filters [Section titled “Filters”](#filters) Filters allow you to trim your input before it’s processed further, so your output contains only relevant resources. ### Operations [Section titled “Operations”](#operations) Set `include` to match operations to be included or `exclude` to match operations to be excluded. Both exact keys and regular expressions are supported. When both rules match the same operation, `exclude` takes precedence over `include`. * include openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
operations: {
include: ['GET /api/v1/foo', '/^[A-Z]+ /api/v1//'],
},
},
},
};
```
* exclude openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
operations: {
exclude: ['GET /api/v1/foo', '/^[A-Z]+ /api/v1//'],
},
},
},
};
```
### Tags [Section titled “Tags”](#tags) Set `include` to match tags to be included or `exclude` to match tags to be excluded. When both rules match the same tag, `exclude` takes precedence over `include`. * include openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
tags: {
include: ['v2'],
},
},
},
};
```
* exclude openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
tags: {
exclude: ['v1'],
},
},
},
};
```
### Deprecated [Section titled “Deprecated”](#deprecated) You can filter out deprecated resources by setting `deprecated` to `false`. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
deprecated: false,
},
},
};
```
### Schemas [Section titled “Schemas”](#schemas) Set `include` to match schemas to be included or `exclude` to match schemas to be excluded. Both exact keys and regular expressions are supported. When both rules match the same schema, `exclude` takes precedence over `include`. * include openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
schemas: {
include: ['Foo', '/^Bar/'],
},
},
},
};
```
* exclude openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
schemas: {
exclude: ['Foo', '/^Bar/'],
},
},
},
};
```
### Parameters [Section titled “Parameters”](#parameters) Set `include` to match parameters to be included or `exclude` to match parameters to be excluded. Both exact keys and regular expressions are supported. When both rules match the same parameter, `exclude` takes precedence over `include`. * include openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
parameters: {
include: ['QueryParameter', '/^MyQueryParameter/'],
},
},
},
};
```
* exclude openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
parameters: {
exclude: ['QueryParameter', '/^MyQueryParameter/'],
},
},
},
};
```
### Request Bodies [Section titled “Request Bodies”](#request-bodies) Set `include` to match request bodies to be included or `exclude` to match request bodies to be excluded. Both exact keys and regular expressions are supported. When both rules match the same request body, `exclude` takes precedence over `include`. * include openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
requestBodies: {
include: ['Payload', '/^SpecialPayload/'],
},
},
},
};
```
* exclude openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
requestBodies: {
exclude: ['Payload', '/^SpecialPayload/'],
},
},
},
};
```
### Responses [Section titled “Responses”](#responses) Set `include` to match responses to be included or `exclude` to match responses to be excluded. Both exact keys and regular expressions are supported. When both rules match the same response, `exclude` takes precedence over `include`. * include openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
responses: {
include: ['Foo', '/^Bar/'],
},
},
},
};
```
* exclude openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
responses: {
exclude: ['Foo', '/^Bar/'],
},
},
},
};
```
### Orphaned resources [Section titled “Orphaned resources”](#orphaned-resources) If you only want to exclude orphaned resources, set `orphans` to `false`. This is the default value when combined with any other filters. If this isn’t the desired behavior, you may want to set `orphans` to `true` to always preserve unused resources. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
orphans: false,
},
},
};
```
### Order [Section titled “Order”](#order) For performance reasons, we don’t preserve the original order when filtering out resources. If maintaining the original order is important to you, set `preserveOrder` to `true`. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
filters: {
preserveOrder: true,
},
},
};
```
## Transforms [Section titled “Transforms”](#transforms) You can think of transforms as deterministic [patches](#patch). They provide an easy way to apply the most commonly used input transformations. ### Enums [Section titled “Enums”](#enums) Your input might contain two types of enums: * enums defined as reusable components (root enums) * non-reusable enums nested within other schemas (inline enums) You may want all enums to be reusable. This is because only root enums are typically exported by plugins. Inline enums will never be directly importable since they’re nested inside other schemas. * root openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
transforms: {
enums: 'root',
},
},
};
```
* inline openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
transforms: {
enums: 'inline',
},
},
};
```
You can customize the naming and casing pattern for `enums` schemas using the `.name` and `.case` options. ### Properties required by default [Section titled “Properties required by default”](#properties-required-by-default) By default, any object schema with a missing `required` keyword is interpreted as “no properties are required.” This is the correct behavior according to the OpenAPI standard. However, some specifications interpret a missing `required` keyword as “all properties should be required.” This option allows you to change the default behavior so that properties are required by default unless explicitly marked as optional. * default openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
transforms: {
propertiesRequiredByDefault: false,
},
},
};
```
* required openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
transforms: {
propertiesRequiredByDefault: true,
},
},
};
```
### Read-write [Section titled “Read-write”](#read-write) Your schemas might contain read-only or write-only fields. Using such schemas directly could mean asking the user to provide a read-only field in requests, or expecting a write-only field in responses. We separate schemas for requests and responses if direct usage would result in such scenarios. * default openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
transforms: {
readWrite: {
requests: '{{name}}Writable',
responses: '{{name}}',
},
},
},
};
```
* disabled openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
transforms: {
readWrite: false,
},
},
};
```
You can customize the naming and casing pattern for `requests` and `responses` schemas using the `.name` and `.case` options. ### Schema Name [Section titled “Schema Name”](#schema-name) Sometimes your schema names are auto-generated or follow a naming convention that produces verbose or awkward type names. You can rename schema component keys throughout the specification, automatically updating all `$ref` pointers. For example, stripping version markers from schema names, removing vendor prefixes, converting naming conventions, or shortening deeply qualified names. * function openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
transforms: {
schemaName: (name) => {
// Strip version markers: ServiceRoot_v1_20_0_ServiceRoot → ServiceRoot
let clean = name.replace(
/([A-Za-z\d]+)_v\d+_\d+_\d+_([A-Za-z\d]*)/g,
(_, p1, p2) => (p2.startsWith(p1) ? p2 : p1 + p2),
);
// Deduplicate prefixes: Foo_Foo → Foo
const m = clean.match(/^([A-Za-z\d]+)_\1([A-Za-z\d]*)$/);
if (m) clean = m[1] + m[2];
return clean;
},
},
},
};
```
* template openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
transforms: {
schemaName: 'Api{{name}}',
},
},
};
```
## Pagination [Section titled “Pagination”](#pagination) Paginated operations are detected by having a pagination keyword in its parameters or request body. By default, we consider the following to be pagination keywords: `after`, `before`, `cursor`, `offset`, `page`, and `start`. You can provide custom pagination keywords using `pagination.keywords`. * extend openapi-ts.config.ts
```js
import { defaultPaginationKeywords } from '@hey-api/openapi-ts';
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
pagination: {
keywords: [
...defaultPaginationKeywords,
'extra',
'pagination',
'keywords',
],
},
},
};
```
* override openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
pagination: {
keywords: [
'custom',
'pagination',
'keywords',
],
},
},
};
```
## Hooks [Section titled “Hooks”](#hooks) Hooks affect runtime behavior but aren’t tied to any single plugin. They can be configured globally via `hooks` or per plugin through the `~hooks` property. * parser openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
hooks: {}, // configure global hooks
},
};
```
* plugin openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
name: '@tanstack/react-query',
'~hooks': {}, // configure plugin hooks
},
],
};
```
We always use the first hook that returns a value. If a hook returns no value, we fall back to less specific hooks until one does. ### Operations Each operation has a list of classifiers that can include `query`, `mutation`, both, or none. Plugins may use these values to decide whether to generate specific output. For example, you usually don’t want to generate [TanStack Query options](https://heyapi.dev/docs/openapi/typescript/plugins/tanstack-query#queries) for PATCH operations. #### Query operations By default, GET operations are classified as `query` operations. #### Mutation operations By default, DELETE, PATCH, POST, and PUT operations are classified as `mutation` operations. #### Example: POST search query [Section titled “Example: POST search query”](#example-post-search-query) Imagine your API has a POST `/search` endpoint that accepts a large payload. By default, it’s classified as a `mutation`, but in practice it behaves like a `query`, and your [state management](https://heyapi.dev/docs/openapi/typescript/state-management) plugin should generate query hooks. You can achieve this by classifying the operation as `query` in a matcher. * isQuery openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
hooks: {
operations: {
isQuery: (op) => {
if (op.method === 'post' && op.path === '/search') {
return true;
}
},
},
},
},
};
```
* getKind openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
hooks: {
operations: {
getKind: (op) => {
if (op.method === 'post' && op.path === '/search') {
return ['query'];
}
},
},
},
},
};
```
### Symbols Each symbol can have a placement function deciding its output location. #### Example: Alphabetic sort [Section titled “Example: Alphabetic sort”](#example-alphabetic-sort) While we work on a better example, let’s imagine a world where it’s desirable to place every symbol in a file named after its initial letter. For example, a function named `Foo` should end up in the file `f.ts`. You can achieve this by using the symbol’s name. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
hooks: {
symbols: {
getFilePath: (symbol) => {
if (symbol.name) {
return symbol.name[0]?.toLowerCase();
}
},
},
},
},
};
```
Most plugins expose configuration options that allow you to rename many of the generated symbols. If you need even more control, use the `getName()` hook. #### Example: Enum naming [Section titled “Example: Enum naming”](#example-enum-naming) By default, generated enums use the same name for both the type and the runtime value. * example index.gen.ts
```ts
export const Flags = {
ALPHA: 'alpha',
BETA: 'beta',
} as const;
export type Flags = (typeof Flags)[keyof typeof Flags];
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
enums: 'javascript',
name: '@hey-api/typescript',
},
],
};
```
While this code works perfectly fine due to TypeScript’s declaration merging, let’s say we want to use a different name for the type. We can accomplish this with the `getName()` hook. * example index.gen.ts
```ts
export const Flags = {
ALPHA: 'alpha',
BETA: 'beta',
} as const;
export type FlagsType = (typeof Flags)[keyof typeof Flags];
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
enums: 'javascript',
name: '@hey-api/typescript',
'~hooks': {
symbols: {
getName({ meta, name, schema }) {
if (schema?.type === 'enum' && meta.category === 'type') {
return `${name}Type`;
}
},
},
},
},
],
};
```
## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Vite Plugin
> Integrate @hey-api/openapi-ts into your Vite 5, 6, 7, or 8 build pipeline with the official Vite plugin.
### About [Section titled “About”](#about) [Vite](https://vite.dev) is a blazing fast frontend build tool powering the next generation of web applications. The Vite plugin integrates `@hey-api/openapi-ts` into the Vite build pipeline, running automatically whenever Vite resolves its configuration – no separate script or manual step required. ## Features [Section titled “Features”](#features) * runs automatically as part of your Vite build * reads your existing [configuration](https://heyapi.dev/docs/openapi/typescript/get-started) (or accepts inline config) * supports Vite 5, 6, 7, and 8 ## Installation [Section titled “Installation”](#installation) You can download `@hey-api/vite-plugin` from npm using your favorite package manager. * npm
```sh
npm install @hey-api/vite-plugin -D -E
```
* pnpm
```sh
pnpm add @hey-api/vite-plugin -D -E
```
* yarn
```sh
yarn add @hey-api/vite-plugin -D -E
```
* bun
```sh
bun add @hey-api/vite-plugin -D
```
## Usage [Section titled “Usage”](#usage) Add the plugin to your `vite.config.ts`: vite.config.ts
```js
import { heyApiPlugin } from '@hey-api/vite-plugin';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [heyApiPlugin()],
});
```
The plugin will automatically pick up your [configuration](https://heyapi.dev/docs/openapi/typescript/configuration) file. You can also pass options inline using the `config` option: vite.config.ts
```js
import { heyApiPlugin } from '@hey-api/vite-plugin';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
heyApiPlugin({
config: {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
},
}),
],
});
```
## Vite Options [Section titled “Vite Options”](#vite-options) You can pass Vite Plugin API options using the `vite` option. For example, to run the plugin only during development: vite.config.ts
```js
import { heyApiPlugin } from '@hey-api/vite-plugin';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
heyApiPlugin({
config: {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
},
vite: {
apply: 'serve',
},
}),
],
});
```
## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Core Plugins
> Learn about the core plugins provided by Hey API.
Apart from being responsible for the default output, core plugins are the foundation for other plugins. Instead of creating their own primitives, other plugins can reuse the artifacts from core plugins. This results in a smaller output size and a better user experience. ## Plugins [Section titled “Plugins”](#plugins) Hey API provides the following core plugins. * [TypeScript](https://heyapi.dev/docs/openapi/typescript/plugins/typescript) * [SDK](https://heyapi.dev/docs/openapi/typescript/plugins/sdk) * [Transformers](https://heyapi.dev/docs/openapi/typescript/plugins/transformers) * [Schemas](https://heyapi.dev/docs/openapi/typescript/plugins/schemas) Need another core plugin? Let us know by [opening an issue](https://github.com/hey-api/openapi-ts/issues). ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Get Started
> Get started with @hey-api/openapi-ts.
[@hey-api/openapi-ts](https://github.com/hey-api/openapi-ts) generates TypeScript code from OpenAPI specifications. Point it at your spec, pick your plugins, and get production-grade code in seconds. Used by companies like Vercel, OpenCode, and PayPal. > *“OpenAPI codegen that just works.”* > > — Guillermo Rauch, CEO of Vercel ### Demo [Section titled “Demo”](#demo) Launch demo ## Features [Section titled “Features”](#features) * production-grade code that compiles * runs in any Node.js 22+ environment * accepts any OpenAPI specification * core plugins for SDKs, types, and schemas * HTTP clients for Fetch API, Angular, Axios, Next.js, Nuxt, and more * 20+ plugins to reduce third-party boilerplate * highly customizable via plugins * [sync with Hey API Registry](https://heyapi.dev/docs/openapi/typescript/integrations) for spec management ## Quick Start [Section titled “Quick Start”](#quick-start) The fastest way to use `@hey-api/openapi-ts` is via npx
```sh
npx @hey-api/openapi-ts -i hey-api/backend -o src/client
```
Congratulations on creating your first client! 🎉 You can learn more about the generated files on the [Output](https://heyapi.dev/docs/openapi/typescript/output) page. ## Installation [Section titled “Installation”](#installation) You can download `@hey-api/openapi-ts` from npm using your favorite package manager. * npm
```sh
npm install @hey-api/openapi-ts -D -E
```
* pnpm
```sh
pnpm add @hey-api/openapi-ts -D -E
```
* yarn
```sh
yarn add @hey-api/openapi-ts -D -E
```
* bun
```sh
bun add @hey-api/openapi-ts -D
```
### Versioning [Section titled “Versioning”](#versioning) This package is in [initial development](https://semver.org/#spec-item-4). Please pin an exact version so you can safely upgrade when you’re ready. We publish [migration notes](https://heyapi.dev/docs/openapi/typescript/migrating) for every breaking release. You might not be impacted by a breaking change if you don’t use the affected features. ## Usage [Section titled “Usage”](#usage) ### CLI [Section titled “CLI”](#cli) Most people run `@hey-api/openapi-ts` via CLI. To do that, add a script to your `package.json` file which will make `openapi-ts` executable through script. package.json
```json
"scripts": {
"openapi-ts": "openapi-ts"
}
```
The above script can be executed by running `npm run openapi-ts` or equivalent command in other package managers. Next, we will create a [configuration](https://heyapi.dev/docs/openapi/typescript/configuration) file and move our options from Quick Start to it. ### Node.js [Section titled “Node.js”](#nodejs) You can also generate output programmatically by calling `createClient()` in a JavaScript/TypeScript file. script.ts
```ts
import { createClient } from '@hey-api/openapi-ts';
createClient({
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
});
```
### Vite [Section titled “Vite”](#vite) If you’re using [Vite](https://vite.dev) 5, 6, 7, or 8, you can integrate `@hey-api/openapi-ts` directly into your build pipeline with `@hey-api/vite-plugin`. Install it alongside the main package: * npm
```sh
npm install @hey-api/vite-plugin -D -E
```
* pnpm
```sh
pnpm add @hey-api/vite-plugin -D -E
```
* yarn
```sh
yarn add @hey-api/vite-plugin -D -E
```
* bun
```sh
bun add @hey-api/vite-plugin -D
```
Then add the plugin to your Vite configuration: vite.config.ts
```ts
import { heyApiPlugin } from '@hey-api/vite-plugin';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
heyApiPlugin({
config: {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
},
}),
],
});
```
See the [Vite](https://heyapi.dev/docs/openapi/typescript/configuration/vite) page for full configuration options. ### Configuration [Section titled “Configuration”](#configuration) It’s a good practice to extract your configuration into a separate file. Learn how to do that and discover available options on the [Configuration](https://heyapi.dev/docs/openapi/typescript/configuration) page. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Hey API Platform
> Automate your client generation with our OpenAPI specifications storage.
Caution This feature is in development! 🎉 Try it out and provide feedback on [GitHub](https://github.com/orgs/hey-api/discussions/1773). You can automate your client generation with Hey API Platform thanks to reproducible builds. Create dependency links between your clients and APIs, and watch the magic unfold. It’s completely language and codegen agnostic. ## Features [Section titled “Features”](#features) * API version history * real-time updates * reproducible builds * language and codegen agnostic (TypeScript/Python/Go/Java/etc codegens are welcome) ## Upload Specifications [Section titled “Upload Specifications”](#upload-specifications) Before you can generate clients, you must publish your OpenAPI specifications to Hey API. ### Prerequisites [Section titled “Prerequisites”](#prerequisites) 1. Create a **free account** with [Hey API](https://app.heyapi.dev). 2. Create a new **organization** and **project** for your API provider. We recommend your naming matches your GitHub structure as it will be referenced by API clients. For example, we are using **hey-api/backend** for the platform. 3. Inside your project, go to *Integrations* > *APIs* and generate an **API key**. Keep this value secret, it will be used to upload files. ### Add GitHub CI workflow [Section titled “Add GitHub CI workflow”](#add-github-ci-workflow) Once you have your API key, you can start uploading OpenAPI specifications on every API build. We’ll use our [GitHub Action](https://github.com/marketplace/actions/upload-openapi-spec-by-hey-api), but you can also make the API call manually if you’re not using GitHub. Create a new GitHub workflow or add an upload step to an existing workflow inside your API codebase. The example below will upload your OpenAPI specification to Hey API on every pull request and push to the `main` branch. github-workflow\.yml
```yaml
name: Upload OpenAPI Specification
on:
push:
branches:
- main
pull_request:
jobs:
upload-openapi-spec:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Upload OpenAPI spec
uses: hey-api/upload-openapi-spec@v1.3.0
with:
path-to-file: path/to/openapi.json
tags: optional,custom,tags
env:
API_KEY: ${{ secrets.HEY_API_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
### Inputs [Section titled “Inputs”](#inputs) To successfully upload an OpenAPI specification, you need to provide the following inputs (see `with` in the example above) #### `path-to-file` [Section titled “path-to-file”](#path-to-file) A relative path to your OpenAPI file within the repository. Note that you might need an additional step in your GitHub workflow to generate this file (see [FastAPI example](https://fastapi.tiangolo.com/how-to/extending-openapi/#generate-the-openapi-schema)). #### `tags` (optional) [Section titled “tags (optional)”](#tags-optional) A comma-separated string value representing any custom tags you wish to add to your OpenAPI specification. ### Environment Variables [Section titled “Environment Variables”](#environment-variables) In addition to the required `path-to-file` input, you must provide the following environment variables. #### `API_KEY` [Section titled “API\_KEY”](#api_key) This is the project API key you obtained from [Hey API](https://app.heyapi.dev). Caution Personal API keys can’t be used to upload specifications. #### `GITHUB_TOKEN` [Section titled “GITHUB\_TOKEN”](#github_token) This variable will be available inside your workflow by default. It’s used to fetch information about your repository, i.e., default branch. ## Generate Clients [Section titled “Generate Clients”](#generate-clients) You can generate clients from public projects or any private projects you can access. The setup is largely the same, you want to configure the input path used by your codegen. * Hey API
```sh
npx @hey-api/openapi-ts -i hey-api/backend -o src/client
```
* OpenAPI TypeScript
```sh
npx openapi-typescript \
https://get.heyapi.dev/hey-api/backend \
-o schema.ts
```
* Orval
```sh
npx orval \
--input https://get.heyapi.dev/hey-api/backend \
--output ./src/client.ts
```
* Other
```sh
other-cli \
--input https://get.heyapi.dev/hey-api/backend \
--output refer/to/other/tools/docs
```
By default, we preserve the current behavior and return the latest specification. Let’s have a closer look at the input path and change that. ## Get API [Section titled “Get API”](#get-api) As you can deduce from the examples above, the default command for fetching OpenAPI specifications looks like this.
```plaintext
https://get.heyapi.dev//
```
If you created an organization `foo` with project `bar` earlier, your URL would look like this.
```plaintext
https://get.heyapi.dev/foo/bar
```
### Auth [Section titled “Auth”](#auth) Projects are private by default, you will need to be authenticated to download OpenAPI specifications. We recommend using [project API keys](#prerequisites) in CI workflows and [personal API keys](https://app.heyapi.dev/settings/user/apis) for local development. Once you have your API key, you can authenticate the request using the `Authorization` header or `api_key` query parameter.
```plaintext
https://get.heyapi.dev/foo/bar?api_key=
```
Congratulations on fetching your first OpenAPI specification! 🎉 ### Filters [Section titled “Filters”](#filters) The default behavior returns the last uploaded specification. This might not be what you want. You can use a range of filters to narrow down the possible specifications, or pin your builds to an exact version. #### `branch` [Section titled “branch”](#branch) You can fetch the last build from branch by providing the `branch` query parameter.
```plaintext
https://get.heyapi.dev/foo/bar?branch=production
```
#### `commit_sha` [Section titled “commit\_sha”](#commit_sha) You can fetch an exact specification by providing the `commit_sha` query parameter. This will always return the same file.
```plaintext
https://get.heyapi.dev/foo/bar?commit_sha=0eb34c2024841ce95620f3ec02a2fea164ea4e9d
```
#### `tags` [Section titled “tags”](#tags) If you’re tagging your specifications with [custom tags](#tags-optional), you can use them to filter the results. When you provide multiple tags, only the first match will be returned.
```plaintext
https://get.heyapi.dev/foo/bar?tags=optional,custom,tags
```
#### `version` [Section titled “version”](#version) Every OpenAPI document contains a required version field. You can use this value to fetch the last uploaded specification matching the value.
```plaintext
https://get.heyapi.dev/foo/bar?version=1.0.0
```
## Feedback [Section titled “Feedback”](#feedback) We’d love your feedback! You can contact us on social media (search Hey API), [email](mailto:lubos@heyapi.dev), or [GitHub](https://github.com/orgs/hey-api/discussions/1773). ## Pricing [Section titled “Pricing”](#pricing) The platform is currently in beta with our focus being on delivering a great experience. We plan to announce pricing once we have gathered enough data around usage patterns. However, we can guarantee there will always be a free plan available. Our mission to bring the finest tooling for working with APIs remains unchanged.
# License
> License FAQ.
### MIT License [Section titled “MIT License”](#mit-license) Copyright (c) Hey API Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# Migrating
> Migrating to @hey-api/openapi-ts.
While we try to avoid breaking changes, sometimes it’s unavoidable in order to offer you the latest features. This page lists changes that require updates to your code. If you run into a problem with migration, please [open an issue](https://github.com/hey-api/openapi-ts/issues). ## v0.98.0 [Section titled “v0.98.0”](#v0980) ### Declarative configuration [Section titled “Declarative configuration”](#declarative-configuration) This is an internal change that simplifies the configuration and plugin APIs. The generated output should be unaffected, please [open an issue](https://github.com/hey-api/openapi-ts/issues) if that’s not the case. If you have custom plugins, refer to the [custom plugin guide](https://heyapi.dev/docs/openapi/typescript/plugins/custom) for the latest instructions. ## v0.97.0 [Section titled “v0.97.0”](#v0970) ### Changed `runtimeConfigPath` behavior [Section titled “Changed runtimeConfigPath behavior”](#changed-runtimeconfigpath-behavior) This was a known, long-standing issue confusing first-time users. Before, defining client `runtimeConfigPath` value would paste it verbatim to the generated output. This release changes the behavior to resolve relative to the output folder. ### Changed Ky client behavior [Section titled “Changed Ky client behavior”](#changed-ky-client-behavior) The Ky client was updated to be more intuitive. Some Ky options now need to be passed via the `kyOptions` field and you need to pass `undefined` to unset an option. ### Changed error interceptors behavior [Section titled “Changed error interceptors behavior”](#changed-error-interceptors-behavior) Error interceptors now receive the result of the previous error interceptor. This aligns their behavior with request and response interceptors. This change only affects you if you use multiple interceptors. ### Optional client request and response [Section titled “Optional client request and response”](#optional-client-request-and-response) The returned request and response objects are now typed as optional. This aligns the types with the actual runtime behavior, which remains unchanged. ### Respect `throwOnError` option [Section titled “Respect throwOnError option”](#respect-throwonerror-option) Previously, there were instances where setting `throwOnError` to `false` would still throw an error. This most commonly happened when request validation failed. With this change, `throwOnError` is now truly respected. ## v0.96.0 [Section titled “v0.96.0”](#v0960) ### Removed Node 20 support [Section titled “Removed Node 20 support”](#removed-node-20-support) This release bumps the minimum required Node version to 22.13. ## v0.95.0 [Section titled “v0.95.0”](#v0950) ### Validator request schemas [Section titled “Validator request schemas”](#validator-request-schemas) Valibot and Zod plugins no longer export composite request `Data` schemas. Instead, each layer is exported as a separate schema. If you’re using validators with SDKs, you can preserve the composite schema with `shouldExtract`: * Zod openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'sdk',
validator: 'zod',
},
{
name: 'zod',
requests: {
shouldExtract: true,
},
},
],
};
```
* Valibot openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'sdk',
validator: 'valibot',
},
{
name: 'valibot',
requests: {
shouldExtract: true,
},
},
],
};
```
### Removed `plugin.getSymbol()` function [Section titled “Removed plugin.getSymbol() function”](#removed-plugingetsymbol-function) This function has been removed. You can use `plugin.querySymbol()` instead. It accepts the same arguments and returns the same result. ## v0.93.0 [Section titled “v0.93.0”](#v0930) ### Removed resolver node [Section titled “Removed resolver node”](#removed-resolver-node) Valibot and Zod plugins no longer expose the `enum.nodes.nullable` node. Both plugins were refactored so that nullable values are handled outside of resolvers. ## v0.92.0 [Section titled “v0.92.0”](#v0920) ### Updated Symbol interface [Section titled “Updated Symbol interface”](#updated-symbol-interface) The `exportFrom` property has been replaced with the `getExportFromFilePath()` function. This allows you to dynamically determine export paths based on symbol properties. This is a low-level feature, so you’re most likely unaffected. ## v0.91.0 [Section titled “v0.91.0”](#v0910) ### Removed CommonJS (CJS) support [Section titled “Removed CommonJS (CJS) support”](#removed-commonjs-cjs-support) `@hey-api/openapi-ts` is now ESM-only. This change simplifies the codebase, improves tree-shaking, and enables better integration with modern bundlers and TypeScript tooling. CommonJS entry points (`require()`, `module.exports`) are no longer supported. If you are in a CJS environment, you can still load the package dynamically using `import()` like:
```js
const { defineConfig } = await import('@hey-api/openapi-ts');
```
If you have previously written:
```js
const { defineConfig } = require('@hey-api/openapi-ts');
```
Migrate by updating your static imports:
```js
import { defineConfig } from '@hey-api/openapi-ts';
```
If your environment cannot use ESM, pin to a previous version. ## v0.90.0 [Section titled “v0.90.0”](#v0900) ### Resolvers API [Section titled “Resolvers API”](#resolvers-api) The [Resolvers API](https://heyapi.dev/docs/openapi/typescript/plugins/concepts/resolvers) has been simplified and expanded to provide a more consistent behavior across plugins. You can view a few common examples on the [Resolvers](https://heyapi.dev/docs/openapi/typescript/plugins/concepts/resolvers) page. ### Structure API [Section titled “Structure API”](#structure-api) The [SDK plugin](https://heyapi.dev/docs/openapi/typescript/plugins/sdk) and [Angular plugin](https://heyapi.dev/docs/openapi/typescript/plugins/angular) now implement the Structure API, enabling more complex structures and fixing several known issues. Some Structure APIs are incompatible with the previous configuration, most notably the `methodNameBuilder` function, which accepted the operation object as an argument. You can read the [SDK Output](https://heyapi.dev/docs/openapi/typescript/plugins/sdk#output) section to familiarize yourself with the Structure API. Please [open an issue](https://github.com/hey-api/openapi-ts/issues) if you’re unable to migrate your configuration to the new syntax. ## v0.89.0 [Section titled “v0.89.0”](#v0890) ### Prefer named exports [Section titled “Prefer named exports”](#prefer-named-exports) This release changes the default for `index.ts` to prefer named exports. Named exports may lead to better IDE and bundler performance compared to asterisk (`*`) as your tooling doesn’t have to inspect the underlying module to discover exports. While this change is merely cosmetic, you can set `output.preferExportAll` to `true` if you prefer to use the asterisk. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
preferExportAll: true,
},
};
```
### Removed `symbol:setValue:*` events [Section titled “Removed symbol:setValue:\* events”](#removed-symbolsetvalue-events) These events have been removed in favor of `node:set:*` events. ## v0.88.0 [Section titled “v0.88.0”](#v0880) ### Removed `compiler` and `tsc` exports [Section titled “Removed compiler and tsc exports”](#removed-compiler-and-tsc-exports) This release removes the `compiler` utility functions. Instead, it introduces a new TypeScript DSL exposed under the `$` symbol. All plugins now use this interface, so you may notice slight changes in the generated output. ## v0.87.0 [Section titled “v0.87.0”](#v0870) ### Removed legacy clients [Section titled “Removed legacy clients”](#removed-legacy-clients) This release removes support for legacy clients and plugins. Please migrate to the new clients if you haven’t done so yet. If you’re unable to do so due to a missing feature, let us know on [GitHub](https://github.com/hey-api/openapi-ts/issues). ## v0.86.0 [Section titled “v0.86.0”](#v0860) ### Removed Node 18 support [Section titled “Removed Node 18 support”](#removed-node-18-support) This release bumps the minimum required Node version to 20.19. ## v0.85.0 [Section titled “v0.85.0”](#v0850) ### Updated `output` options [Section titled “Updated output options”](#updated-output-options) We made the `output` configuration more consistent by using `null` to represent disabled options. This change does not affect boolean options. openapi-ts.config.ts
```diff
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
-format: false,
+format: null,
-lint: false,
+lint: null,
path: 'src/client',
-tsConfigPath: 'off',
+tsConfigPath: null,
},
};
```
### Updated Pinia Colada query options [Section titled “Updated Pinia Colada query options”](#updated-pinia-colada-query-options) Pinia Colada query options now use `defineQueryOptions` to improve reactivity support. Instead of calling the query options function, you can use one of the following approaches. * no params colada.gen.ts
```ts
useQuery(getPetsQuery);
```
* constant colada.gen.ts
```ts
useQuery(getPetByIdQuery, () => ({
path: {
petId: 1,
},
}));
```
* reactive colada.gen.ts
```ts
const petId = ref(1);
useQuery(getPetByIdQuery, () => ({
path: {
petId: petId.value,
},
}));
```
* properties colada.gen.ts
```ts
const petId = ref(1);
useQuery(() => ({
...getPetByIdQuery({
path: { petId: petId.value as number },
}),
enabled: () => petId.value !== null,
}));
```
## v0.84.0 [Section titled “v0.84.0”](#v0840) ### Symbol API [Section titled “Symbol API”](#symbol-api) This release improves the Symbol API, which adds the capability to place symbols in arbitrary files. We preserved the previous output structure for all plugins except Angular. You can preserve the previous Angular output by writing your own [placement function](https://heyapi.dev/docs/openapi/typescript/configuration/parser#hooks-symbols). ### TypeScript renderer [Section titled “TypeScript renderer”](#typescript-renderer) We ship a dedicated TypeScript renderer for `.ts` files. This release improves the renderer’s ability to group and sort imported modules, resulting in a more polished output. ### Removed `output` plugin option [Section titled “Removed output plugin option”](#removed-output-plugin-option) Due to the Symbol API release, this option has been removed from the Plugin API. ## v0.83.0 [Section titled “v0.83.0”](#v0830) ### Symbol API [Section titled “Symbol API”](#symbol-api-1) This release adds the Symbol API, which significantly reduces the risk of naming collisions. While the generated output should only include formatting changes, this feature introduces breaking changes to the Plugin API that affect custom plugins. We will update the [custom plugin guide](https://heyapi.dev/docs/openapi/typescript/plugins/custom) once the Plugin API becomes more stable. ### Removed `groupByTag` Pinia Colada option [Section titled “Removed groupByTag Pinia Colada option”](#removed-groupbytag-pinia-colada-option) This option has been removed to provide a more consistent API across plugins. We plan to bring it back in a future release. ## v0.82.0 [Section titled “v0.82.0”](#v0820) ### Hooks API [Section titled “Hooks API”](#hooks-api) This release adds the [Hooks API](https://heyapi.dev/docs/openapi/typescript/configuration/parser#hooks), giving you granular control over which operations generate queries and mutations. As a result, we tightened the previous behavior and POST operations no longer generate queries by default. To preserve the old behavior, add a custom matcher. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
parser: {
hooks: {
operations: {
isQuery: (op) => (op.method === 'post' ? true : undefined),
},
},
},
};
```
## v0.81.0 [Section titled “v0.81.0”](#v0810) ### Server-Sent Events (SSE) [Section titled “Server-Sent Events (SSE)”](#server-sent-events-sse) This release adds support for server-sent events (SSE). Instead of treating `text/event-stream` content types as regular HTTP methods, we now generate SSE streams. In practice, you will want to update your affected endpoints to process streamed events. * before client.gen.ts
```js
const { data } = await foo();
console.log(data.type);
```
* after client.gen.ts
```js
const { stream } = await foo();
for await (const event of stream) {
console.log(event.type);
}
```
## v0.80.0 [Section titled “v0.80.0”](#v0800) ### Added Zod 4 and Zod Mini [Section titled “Added Zod 4 and Zod Mini”](#added-zod-4-and-zod-mini) This release adds support for Zod 4 and Zod Mini. By default, the `zod` plugin will generate output for Zod 4. If you want to preserve the previous output for Zod 3 or use Zod Mini, set `compatibilityVersion` to `3` or `mini`. * Zod 3 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 3,
},
],
};
```
* Zod Mini openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 'mini',
},
],
};
```
## v0.79.0 [Section titled “v0.79.0”](#v0790) ### Removed `typescript+namespace` enums mode [Section titled “Removed typescript+namespace enums mode”](#removed-typescriptnamespace-enums-mode) Due to a simpler TypeScript plugin implementation, the `typescript+namespace` enums mode is no longer necessary. This mode was used in the past to group inline enums under the same namespace. With the latest changes, this behavior is no longer supported. You can either choose to ignore inline enums (default), or use the `enums` transform (added in v0.78.0) to convert them into reusable components which will get exported as usual. ## v0.78.0 [Section titled “v0.78.0”](#v0780) ### Added `parser` options [Section titled “Added parser options”](#added-parser-options) Previously, `@hey-api/typescript` would generate correct types, but the validator plugins would have to re-implement the same logic or generate schemas that didn’t match the generated types. Since neither option was ideal, this release adds a dedicated place for `parser` options. Parser is responsible for preparing the input so plugins can generate more accurate output with less effort. You can learn more about configuring parser on the [Parser](https://heyapi.dev/docs/openapi/typescript/configuration/parser) page. ### Moved `input` options [Section titled “Moved input options”](#moved-input-options) The following options were moved to the new `parser` group. * `input.filters` moved to `parser.filters` * `input.pagination` moved to `parser.pagination` * `input.patch` moved to `parser.patch` * `input.validate_EXPERIMENTAL` moved to `parser.validate_EXPERIMENTAL` ### Updated `typescript` options [Section titled “Updated typescript options”](#updated-typescript-options) The following options were renamed. * `enumsCase` moved to `enums.case` * `enumsConstantsIgnoreNull` moved to `enums.constantsIgnoreNull` ### Moved `typescript` options [Section titled “Moved typescript options”](#moved-typescript-options) The following options were moved to the new `parser` group. * `exportInlineEnums` moved to `parser.transforms.enums` * `readOnlyWriteOnlyBehavior` moved to `parser.transforms.readWrite.enabled` * `readableNameBuilder` moved to `parser.transforms.readWrite.responses.name` * `writableNameBuilder` moved to `parser.transforms.readWrite.requests.name` ### Updated `readWrite.responses` name [Section titled “Updated readWrite.responses name”](#updated-readwriteresponses-name) Additionally, the naming pattern for response schemas has changed from `{name}Readable` to `{name}`. This is to prevent your code from breaking by default when using a schema that gets updated with a write-only field. ## v0.77.0 [Section titled “v0.77.0”](#v0770) ### Updated `sdk.validator` option [Section titled “Updated sdk.validator option”](#updated-sdkvalidator-option) Clients can now validate both request and response data. As a result, passing a boolean or string to `validator` will control both of these options. To preserve the previous behavior, set `validator.request` to `false` and `validator.response` to your previous configuration. openapi-ts.config.ts
```diff
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@hey-api/sdk',
-validator: true,
+validator: {
+request: false,
+response: true,
+},
},
],
};
```
### Updated Plugin API [Section titled “Updated Plugin API”](#updated-plugin-api) Please refer to the [custom plugin](https://heyapi.dev/docs/openapi/typescript/plugins/custom) tutorial for the latest guide. ## v0.76.0 [Section titled “v0.76.0”](#v0760) ### Single Valibot schema per request [Section titled “Single Valibot schema per request”](#single-valibot-schema-per-request) Previously, we generated a separate schema for each endpoint parameter and request body. In v0.76.0, a single request schema is generated for the whole endpoint. It may contain a request body, parameters, and headers.
```ts
const vData = v.object({
body: v.optional(
v.object({
foo: v.optional(v.string()),
bar: v.optional(v.union([v.number(), v.null()])),
}),
),
headers: v.optional(v.never()),
path: v.object({
baz: v.string(),
}),
query: v.optional(v.never()),
});
```
If you need to access individual fields, you can do so using the [`.entries`](https://valibot.dev/api/object/) API. For example, we can get the request body schema with `vData.entries.body`. ## v0.75.0 [Section titled “v0.75.0”](#v0750) ### Updated TanStack Query options [Section titled “Updated TanStack Query options”](#updated-tanstack-query-options) The TanStack Query plugin options have been expanded to support more naming and casing patterns. As a result, the following options have been renamed. * `queryOptionsNameBuilder` renamed to `queryOptions` * `infiniteQueryOptionsNameBuilder` renamed to `infiniteQueryOptions` * `mutationOptionsNameBuilder` renamed to `mutationOptions` * `queryKeyNameBuilder` renamed to `queryKeys` * `infiniteQueryKeyNameBuilder` renamed to `infiniteQueryKeys` ### Added `plugin.forEach()` method [Section titled “Added plugin.forEach() method”](#added-pluginforeach-method) This method replaces the `.subscribe()` method. Additionally, `.forEach()` is executed immediately, which means we don’t need the `before` and `after` events – simply move your code before and after the `.forEach()` block.
```diff
-plugin.subscribe('operation', (event) => {
// do something with event
-});
-plugin.subscribe('schema', (event) => {
+plugin.forEach('operation', 'schema', (event) => {
// do something with event
});
```
## v0.74.0 [Section titled “v0.74.0”](#v0740) ### Single Zod schema per request [Section titled “Single Zod schema per request”](#single-zod-schema-per-request) Previously, we generated a separate schema for each endpoint parameter and request body. In v0.74.0, a single request schema is generated for the whole endpoint. It may contain a request body, parameters, and headers.
```ts
const zData = z.object({
body: z
.object({
foo: z.string().optional(),
bar: z.union([z.number(), z.null()]).optional(),
})
.optional(),
headers: z.never().optional(),
path: z.object({
baz: z.string(),
}),
query: z.never().optional(),
});
```
If you need to access individual fields, you can do so using the [`.shape`](https://zod.dev/api?id=shape) API. For example, we can get the request body schema with `zData.shape.body`. ## v0.73.0 [Section titled “v0.73.0”](#v0730) ### Bundle `@hey-api/client-*` plugins [Section titled “Bundle @hey-api/client-\* plugins”](#bundle-hey-apiclient--plugins) In previous releases, you had to install a separate client package to generate a fully working output, e.g., `npm install @hey-api/client-fetch`. This created a few challenges: getting started was slower, upgrading was sometimes painful, and bundling too. Beginning with v0.73.0, all Hey API clients are bundled by default and don’t require installing any additional dependencies. You can remove any installed client packages and re-run `@hey-api/openapi-ts`.
```sh
npm uninstall @hey-api/client-fetch
```
## v0.72.0 [Section titled “v0.72.0”](#v0720) ### Added `sdk.classStructure` option [Section titled “Added sdk.classStructure option”](#added-sdkclassstructure-option) When generating class-based SDKs, we now try to infer the ideal structure using `operationId` keywords. If you’d like to preserve the previous behavior, set `classStructure` to `off`. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
classStructure: 'off',
name: '@hey-api/sdk',
},
],
};
```
## v0.71.0 [Section titled “v0.71.0”](#v0710) ### Renamed `sdk.serviceNameBuilder` option [Section titled “Renamed sdk.serviceNameBuilder option”](#renamed-sdkservicenamebuilder-option) This option has been renamed to `sdk.classNameBuilder` to better represent its functionality. Additionally, it’s no longer set by default. To preserve the previous behavior, update your configuration. openapi-ts.config.ts
```diff
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
+classNameBuilder: '{{name}}Service',
name: '@hey-api/sdk',
-serviceNameBuilder: '{{name}}Service',
},
],
};
```
## v0.68.0 [Section titled “v0.68.0”](#v0680) ### Upgraded input filters [Section titled “Upgraded input filters”](#upgraded-input-filters) Input filters now avoid generating invalid output without requiring you to specify every missing schema as in the previous releases. As part of this release, we changed the way filters are configured and removed the support for regular expressions. Let us know if regular expressions are still useful for you and want to bring them back! * include openapi-ts.config.ts
```diff
export default {
input: {
// match only the schema named `foo` and `GET` operation for the `/api/v1/foo` path
filters: {
operations: {
include: ['GET /api/v1/foo'],
},
schemas: {
include: ['foo'],
},
},
-include: '^(#/components/schemas/foo|#/paths/api/v1/foo/get)$',
path: 'hey-api/backend', // sign up at app.heyapi.dev
},
output: 'src/client',
plugins: ['@hey-api/client-fetch'],
};
```
* exclude openapi-ts.config.ts
```diff
export default {
input: {
// match everything except for the schema named `foo` and `GET` operation for the `/api/v1/foo` path
-exclude: '^(#/components/schemas/foo|#/paths/api/v1/foo/get)$',
filters: {
operations: {
exclude: ['GET /api/v1/foo'],
},
schemas: {
exclude: ['foo'],
},
},
path: 'hey-api/backend', // sign up at app.heyapi.dev
},
output: 'src/client',
plugins: ['@hey-api/client-fetch'],
};
```
## v0.67.0 [Section titled “v0.67.0”](#v0670) ### Respecting `moduleResolution` value in `tsconfig.json` [Section titled “Respecting moduleResolution value in tsconfig.json”](#respecting-moduleresolution-value-in-tsconfigjson) This release introduces functionality related to your `tsconfig.json` file. The initial feature properly respects the value of your `moduleResolution` field. If you’re using `nodenext`, the relative module paths in your output will be appended with `.js`. To preserve the previous behavior where we never appended `.js` to relative module paths, set `output.tsConfigPath` to `off`. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
tsConfigPath: 'off',
},
};
```
## v0.66.0 [Section titled “v0.66.0”](#v0660) ### Read-only and write-only fields [Section titled “Read-only and write-only fields”](#read-only-and-write-only-fields) Starting with v0.66.0, `@hey-api/typescript` will generate separate types for payloads and responses if it detects any read-only or write-only fields. To preserve the previous behavior and generate a single type regardless, set `readOnlyWriteOnlyBehavior` to `off`. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@hey-api/typescript',
readOnlyWriteOnlyBehavior: 'off',
},
],
};
```
## v0.64.0 [Section titled “v0.64.0”](#v0640) ### Added `ClientOptions` interface [Section titled “Added ClientOptions interface”](#added-clientoptions-interface) The `Config` interface now accepts an optional generic extending `ClientOptions` instead of `boolean` type `ThrowOnError`.
```diff
-type Foo = Config;
+type Foo = Config<{ throwOnError: false }>;
```
### Added `client.baseUrl` option [Section titled “Added client.baseUrl option”](#added-clientbaseurl-option) You can use this option to configure the default base URL for the generated client. By default, we will attempt to resolve the first defined server or infer the base URL from the input path. If you’d like to preserve the previous behavior, set `baseUrl` to `false`. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
baseUrl: false,
name: '@hey-api/client-fetch',
},
],
};
```
## v0.63.0 [Section titled “v0.63.0”](#v0630) ### Client plugins [Section titled “Client plugins”](#client-plugins) Clients are now plugins generating their own `client.gen.ts` file. There’s no migration needed if you’re using CLI. If you’re using the configuration file, move `client` options to `plugins`. openapi-ts.config.ts
```diff
export default {
-client: '@hey-api/client-fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
+plugins: ['@hey-api/client-fetch'],
};
```
### Added `client.gen.ts` file [Section titled “Added client.gen.ts file”](#added-clientgents-file) Related to above, the internal `client` instance previously located in `sdk.gen.ts` is now defined in `client.gen.ts`. If you’re importing it in your code, update the import module.
```diff
-import { client } from 'client/sdk.gen';
+import { client } from 'client/client.gen';
```
### Moved `sdk.throwOnError` option [Section titled “Moved sdk.throwOnError option”](#moved-sdkthrowonerror-option) This SDK configuration option has been moved to the client plugins where applicable. Not every client can be configured to throw on error, so it didn’t make sense to expose the option when it didn’t have any effect. openapi-ts.config.ts
```diff
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
{
name: '@hey-api/client-fetch',
+throwOnError: true,
},
{
name: '@hey-api/sdk',
-throwOnError: true,
},
],
};
```
## v0.62.0 [Section titled “v0.62.0”](#v0620) ### Changed parser [Section titled “Changed parser”](#changed-parser) Formerly known as the experimental parser, this is now the default parser. This change should not impact the generated output’s functionality. However, there might be cases where this results in breaking changes due to different handling of certain scenarios. If you need to revert to the legacy parser, set the `experimentalParser` flag to `false`. openapi-ts.config.ts
```js
export default {
client: '@hey-api/client-fetch',
experimentalParser: false,
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};
```
Note that the legacy parser is no longer supported and will be removed in the v1 release. ## v0.61.0 [Section titled “v0.61.0”](#v0610) ### Added `auth` option [Section titled “Added auth option”](#added-auth-option) Client package functions `accessToken` and `apiKey` were replaced with a single `auth` function for fetching auth tokens. If your API supports multiple auth mechanisms, you can use the `auth` argument to return the appropriate token.
```diff
import { client } from 'client/sdk.gen';
client.setConfig({
-accessToken: () => '',
-apiKey: () => '',
+auth: (auth) => '',
});
```
Due to conflict with the Axios native `auth` option, we removed support for configuring Axios auth. Please let us know if you require this feature added back. ### Added `watch` option [Section titled “Added watch option”](#added-watch-option) While this is a new feature, supporting it involved replacing the `@apidevtools/json-schema-ref-parser` dependency with our own implementation. Since this was a big change, we’re applying caution and marking this as a breaking change. ### Changed `parseAs: 'auto'` behavior [Section titled “Changed parseAs: 'auto' behavior”](#changed-parseas-auto-behavior) The Fetch API client will return raw response body as `ReadableStream` when `Content-Type` response header is undefined and `parseAs` is `auto`. ## v0.60.0 [Section titled “v0.60.0”](#v0600) ### Added `sdk.transformer` option [Section titled “Added sdk.transformer option”](#added-sdktransformer-option) When generating SDKs, you now have to specify `transformer` in order to modify response data. By default, adding `@hey-api/transformers` to your plugins will only produce additional output. To preserve the previous functionality, set `sdk.transformer` to `true`. openapi-ts.config.ts
```js
export default {
client: '@hey-api/client-fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
dates: true,
name: '@hey-api/transformers',
},
{
name: '@hey-api/sdk',
transformer: true,
},
],
};
```
## v0.59.0 [Section titled “v0.59.0”](#v0590) ### Added `logs.level` option [Section titled “Added logs.level option”](#added-logslevel-option) You can now configure different log levels. As part of this feature, we had to introduce a breaking change by moving the `debug` option to `logs.level`. This will affect you if you’re calling `@hey-api/openapi-ts` from Node.js (not CLI) or using the configuration file. openapi-ts.config.ts
```diff
export default {
client: '@hey-api/client-fetch',
-debug: true,
input: 'hey-api/backend', // sign up at app.heyapi.dev
logs: {
+level: 'debug',
},
output: 'src/client',
};
```
### Updated default `plugins` [Section titled “Updated default plugins”](#updated-default-plugins) `@hey-api/schemas` has been removed from the default plugins. To continue using it, add it to your plugins array. openapi-ts.config.ts
```js
export default {
client: '@hey-api/client-fetch',
experimentalParser: true,
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@hey-api/schemas',
],
};
```
## v0.58.0 [Section titled “v0.58.0”](#v0580) ### Removed `schemas.gen.ts` re-export [Section titled “Removed schemas.gen.ts re-export”](#removed-schemasgents-re-export) `index.ts` will no longer re-export `schemas.gen.ts` to reduce the chance of producing broken output. Please update your code to import from `schemas.gen.ts` directly.
```diff
-import { mySchema } from 'client';
+import { mySchema } from 'client/schemas.gen';
```
### Removed `transformers.gen.ts` re-export [Section titled “Removed transformers.gen.ts re-export”](#removed-transformersgents-re-export) `index.ts` will no longer re-export `transformers.gen.ts` to reduce the chance of producing broken output. Please update your code to import from `transformers.gen.ts` directly.
```diff
-import { myTransformer } from 'client';
+import { myTransformer } from 'client/transformers.gen';
```
### Added `output.clean` option [Section titled “Added output.clean option”](#added-outputclean-option) By default, the `output.path` folder will be emptied on every run. To preserve the previous behavior, set `output.clean` to `false`. openapi-ts.config.ts
```js
export default {
client: '@hey-api/client-fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
clean: false,
path: 'src/client',
},
};
```
### Added `typescript.identifierCase` option [Section titled “Added typescript.identifierCase option”](#added-typescriptidentifiercase-option) **This change affects only the experimental parser.** By default, the generated TypeScript interfaces will follow the PascalCase naming convention. In the previous versions, we tried to preserve the original name as much as possible. To keep the previous behavior, set `typescript.identifierCase` to `preserve`. openapi-ts.config.ts
```js
export default {
client: '@hey-api/client-fetch',
experimentalParser: true,
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
identifierCase: 'preserve',
name: '@hey-api/typescript',
},
],
};
```
## v0.57.0 [Section titled “v0.57.0”](#v0570) ### Renamed `@hey-api/services` plugin [Section titled “Renamed @hey-api/services plugin”](#renamed-hey-apiservices-plugin) This plugin has been renamed to `@hey-api/sdk`. ### Changed `sdk.output` value [Section titled “Changed sdk.output value”](#changed-sdkoutput-value) To align with the updated name, the `@hey-api/sdk` plugin will generate an `sdk.gen.ts` file. This will result in a breaking change if you’re importing from `services.gen.ts`. Please update your imports to reflect this change.
```diff
-import { client } from 'client/services.gen';
+import { client } from 'client/sdk.gen';
```
### Renamed `@hey-api/types` plugin [Section titled “Renamed @hey-api/types plugin”](#renamed-hey-apitypes-plugin) This plugin has been renamed to `@hey-api/typescript`. ### Added `typescript.exportInlineEnums` option [Section titled “Added typescript.exportInlineEnums option”](#added-typescriptexportinlineenums-option) By default, inline enums (enums not defined as reusable components in the input file) will be generated only as inlined union types. You can set `exportInlineEnums` to `true` to treat inline enums as reusable components. When `true`, the exported enums will follow the style defined in `enums`. This is a breaking change since in the previous versions, inline enums were always treated as reusable components. To preserve your current output, set `exportInlineEnums` to `true`. This feature works only with the experimental parser. openapi-ts.config.ts
```js
export default {
client: '@hey-api/client-fetch',
experimentalParser: true,
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
exportInlineEnums: true,
name: '@hey-api/typescript',
},
],
};
```
## v0.56.0 [Section titled “v0.56.0”](#v0560) ### Deprecated `tree` in `@hey-api/types` [Section titled “Deprecated tree in @hey-api/types”](#deprecated-tree-in-hey-apitypes) This config option is deprecated and will be removed when the experimental parser becomes the default. ## v0.55.0 [Section titled “v0.55.0”](#v0550) This release adds the ability to filter your OpenAPI specification before it’s processed. This feature will be useful if you are working with a large specification and are interested in generating output only from a small subset. This feature is available only in the experimental parser. In the future, this will become the default parser. To opt-in to the experimental parser, set the `experimentalParser` flag in your configuration to `true`. ### Deprecated `include` in `@hey-api/types` [Section titled “Deprecated include in @hey-api/types”](#deprecated-include-in-hey-apitypes) This config option is deprecated and will be removed when the experimental parser becomes the default. ### Deprecated `filter` in `@hey-api/services` [Section titled “Deprecated filter in @hey-api/services”](#deprecated-filter-in-hey-apiservices) This config option is deprecated and will be removed when the experimental parser becomes the default. ### Added `input.include` option [Section titled “Added input.include option”](#added-inputinclude-option) This config option can be used to replace the deprecated options. It accepts a regular expression string matching against references within the bundled specification. openapi-ts.config.ts
```js
export default {
client: '@hey-api/client-fetch',
experimentalParser: true,
input: {
include: '^(#/components/schemas/foo|#/paths/api/v1/foo/get)$',
path: 'hey-api/backend', // sign up at app.heyapi.dev
},
output: 'src/client',
};
```
The configuration above will process only the schema named `foo` and `GET` operation for the `/api/v1/foo` path. ## v0.54.0 [Section titled “v0.54.0”](#v0540) This release makes plugins first-class citizens. In order to achieve that, the following breaking changes were introduced. ### Removed CLI options [Section titled “Removed CLI options”](#removed-cli-options) The `--types`, `--schemas`, and `--services` CLI options have been removed. You can list which plugins you’d like to use explicitly by passing a list of plugins as `--plugins ` ### Removed `*.export` option [Section titled “Removed \*.export option”](#removed-export-option) Previously, you could explicitly disable export of certain artifacts using the `*.export` option or its shorthand variant. These were both removed. You can now disable export of specific artifacts by manually defining an array of `plugins` and excluding the unwanted plugin. * shorthand openapi-ts.config.ts
```diff
export default {
client: '@hey-api/client-fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
-schemas: false,
+plugins: ['@hey-api/types', '@hey-api/services'],
};
```
* exclude \*.export
```diff
export default {
client: '@hey-api/client-fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
schemas: {
-export: false,
},
+plugins: ['@hey-api/types', '@hey-api/services'],
};
```
### Renamed `schemas.name` option [Section titled “Renamed schemas.name option”](#renamed-schemasname-option) Each plugin definition contains a `name` field. This was conflicting with the `schemas.name` option. As a result, it has been renamed to `nameBuilder`. openapi-ts.config.ts
```diff
export default {
client: '@hey-api/client-fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
schemas: {
-name: (name) => `${name}Schema`,
},
plugins: [
// ...other plugins
{
+nameBuilder: (name) => `${name}Schema`,
name: '@hey-api/schemas',
},
],
};
```
### Removed `services.include` shorthand option [Section titled “Removed services.include shorthand option”](#removed-servicesinclude-shorthand-option) Previously, you could use a string value as a shorthand for the `services.include` configuration option. You can now achieve the same result using the `include` option. openapi-ts.config.ts
```diff
export default {
client: '@hey-api/client-fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
-services: '^MySchema',
plugins: [
// ...other plugins
{
+include: '^MySchema',
name: '@hey-api/services',
},
],
};
```
### Renamed `services.name` option [Section titled “Renamed services.name option”](#renamed-servicesname-option) Each plugin definition contains a `name` field. This was conflicting with the `services.name` option. As a result, it has been renamed to `serviceNameBuilder`. openapi-ts.config.ts
```diff
export default {
client: '@hey-api/client-fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
services: {
-name: '{{name}}Service',
},
plugins: [
// ...other plugins
{
+serviceNameBuilder: '{{name}}Service',
name: '@hey-api/services',
},
],
};
```
### Renamed `types.dates` option [Section titled “Renamed types.dates option”](#renamed-typesdates-option) Previously, you could set `types.dates` to a boolean or a string value, depending on whether you wanted to transform only type strings into dates, or runtime code too. Many people found these options confusing, so they have been simplified to a boolean and extracted into a separate `@hey-api/transformers` plugin. openapi-ts.config.ts
```diff
export default {
client: '@hey-api/client-fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
types: {
-dates: 'types+transform',
},
plugins: [
// ...other plugins
{
+dates: true,
name: '@hey-api/transformers',
},
],
};
```
### Removed `types.include` shorthand option [Section titled “Removed types.include shorthand option”](#removed-typesinclude-shorthand-option) Previously, you could use a string value as a shorthand for the `types.include` configuration option. You can now achieve the same result using the `include` option. openapi-ts.config.ts
```diff
export default {
client: '@hey-api/client-fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
-types: '^MySchema',
plugins: [
// ...other plugins
{
+include: '^MySchema',
name: '@hey-api/types',
},
],
};
```
### Renamed `types.name` option [Section titled “Renamed types.name option”](#renamed-typesname-option) Each plugin definition contains a `name` field. This was conflicting with the `types.name` option. As a result, it has been renamed to `style`. openapi-ts.config.ts
```diff
export default {
client: '@hey-api/client-fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
types: {
-name: 'PascalCase',
},
plugins: [
// ...other plugins
{
name: '@hey-api/types',
+style: 'PascalCase',
},
],
};
```
## v0.53.0 [Section titled “v0.53.0”](#v0530) ### Changed schemas name pattern [Section titled “Changed schemas name pattern”](#changed-schemas-name-pattern) Previously, generated schemas would have their definition names prefixed with `$`. This was problematic when using them with Svelte due to reserved keyword conflicts. The new naming pattern for schemas suffixes their definition names with `Schema`. You can continue using the previous pattern by setting the `schemas.name` configuration option. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
schemas: {
name: (name) => `$${name}`,
},
};
```
### Renamed legacy clients [Section titled “Renamed legacy clients”](#renamed-legacy-clients) Legacy clients were renamed to signal they are deprecated more clearly. To continue using legacy clients, you will need to update your configuration and prefix them with `legacy/`. * fetch openapi-ts.config.ts
```diff
export default {
-client: 'fetch',
+client: 'legacy/fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};
```
* axios openapi-ts.config.ts
```diff
export default {
-client: 'axios',
+client: 'legacy/axios',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};
```
* angular openapi-ts.config.ts
```diff
export default {
-client: 'angular',
+client: 'legacy/angular',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};
```
* node openapi-ts.config.ts
```diff
export default {
-client: 'node',
+client: 'legacy/node',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};
```
* xhr openapi-ts.config.ts
```diff
export default {
-client: 'xhr',
+client: 'legacy/xhr',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};
```
## v0.52.0 [Section titled “v0.52.0”](#v0520) ### Removed internal `client` export [Section titled “Removed internal client export”](#removed-internal-client-export) Previously, client packages would create a default client which you’d then import and configure.
```js
import { client, createClient } from '@hey-api/client-fetch';
createClient({
baseUrl: 'https://example.com',
});
console.log(client.getConfig().baseUrl); // <-- 'https://example.com'
```
This client instance was used internally by services unless overridden. Apart from running `createClient()` twice, people were confused about the meaning of `global` configuration option. Starting with v0.52.0, client packages will not create a default client. Instead, services will define their own client. You can now achieve the same configuration by importing `client` from services and using the new `setConfig()` method.
```js
import { client } from 'client/services.gen';
client.setConfig({
baseUrl: 'https://example.com',
});
console.log(client.getConfig().baseUrl); // <-- 'https://example.com'
```
## v0.51.0 [Section titled “v0.51.0”](#v0510) ### Required `client` option [Section titled “Required client option”](#required-client-option) Client now has to be explicitly specified and `@hey-api/openapi-ts` will no longer generate a legacy Fetch API client by default. To preserve the previous default behavior, set the `client` option to `fetch`. openapi-ts.config.ts
```js
export default {
client: 'fetch',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};
```
## v0.48.0 [Section titled “v0.48.0”](#v0480) ### Changed `methodNameBuilder()` signature [Section titled “Changed methodNameBuilder() signature”](#changed-methodnamebuilder-signature) The `services.methodNameBuilder()` function now provides a single `operation` argument instead of multiple cherry-picked properties from it. openapi-ts.config.ts
```diff
import { createClient } from '@hey-api/openapi-ts';
createClient({
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
services: {
-methodNameBuilder: (service, name) => name,
+methodNameBuilder: (operation) => operation.name,
},
});
```
## v0.46.0 [Section titled “v0.46.0”](#v0460) ### Tree-shakeable services [Section titled “Tree-shakeable services”](#tree-shakeable-services) By default, your services will now support [tree-shaking](https://developer.mozilla.org/docs/Glossary/Tree_shaking). You can either use wildcard imports
```diff
-import { DefaultService } from 'client/services.gen';
+import * as DefaultService from 'client/services.gen';
DefaultService.foo(); // only import needs to be changed
```
or update all references to service classes
```diff
-import { DefaultService } from 'client/services.gen';
+import { foo } from 'client/services.gen';
foo(); // all references need to be changed
```
If you want to preserve the old behavior, you can set the newly exposed `services.asClass` option to `true.` openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
services: {
asClass: true,
},
};
```
## v0.45.0 [Section titled “v0.45.0”](#v0450) ### Removed `client` inference [Section titled “Removed client inference”](#removed-client-inference) `@hey-api/openapi-ts` will no longer infer which client you want to generate. By default, we will create a `fetch` client. If you want a different client, you can specify it using the `client` option. openapi-ts.config.ts
```js
export default {
client: 'axios',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};
```
## v0.44.0 [Section titled “v0.44.0”](#v0440) ### Moved `format` [Section titled “Moved format”](#moved-format) This config option has been moved. You can now configure formatter using the `output.format` option. openapi-ts.config.ts
```diff
export default {
-format: 'prettier',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
+format: 'prettier',
path: 'src/client',
},
};
```
### Moved `lint` [Section titled “Moved lint”](#moved-lint) This config option has been moved. You can now configure linter using the `output.lint` option. openapi-ts.config.ts
```diff
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
-lint: 'eslint',
output: {
+lint: 'eslint',
path: 'src/client',
},
};
```
## v0.43.0 [Section titled “v0.43.0”](#v0430) ### Removed `enums.gen.ts` [Section titled “Removed enums.gen.ts”](#removed-enumsgents) This file has been removed. Instead, enums are exported from `types.gen.ts`. If you use imports from `enums.gen.ts`, you should be able to easily find and replace all instances.
```diff
-import { Foo } from 'client/enums.gen';
+import { Foo } from 'client/types.gen';
```
### Removed `Enum` postfix [Section titled “Removed Enum postfix”](#removed-enum-postfix) Generated enum names are no longer postfixed with `Enum`. You can either alias your imports
```diff
-import { FooEnum } from 'client/types.gen';
+import { Foo as FooEnum } from 'client/types.gen';
console.log(FooEnum.value); // only import needs to be changed
```
or update all references to enums
```diff
-import { FooEnum } from 'client/types.gen';
+import { Foo } from 'client/types.gen';
console.log(Foo.value); // all references need to be changed
```
### Moved `enums` [Section titled “Moved enums”](#moved-enums) This config option has been moved. You can now configure enums using the `types.enums` option. openapi-ts.config.ts
```diff
export default {
-enums: 'javascript',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
types: {
+enums: 'javascript',
},
};
```
## v0.42.0 [Section titled “v0.42.0”](#v0420) ### Changed `format` [Section titled “Changed format”](#changed-format) This config option has changed. You now need to specify a value (`biome` or `prettier`) to format the output (default: `false`).
```js
export default {
format: 'prettier',
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
}
```
### Changed `lint` [Section titled “Changed lint”](#changed-lint) This config option has changed. You now need to specify a value (`biome` or `eslint`) to lint the output (default: `false`).
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
lint: 'eslint',
output: 'src/client',
}
```
### Moved `operationId` [Section titled “Moved operationId”](#moved-operationid) This config option has been moved. You can now configure it using the `services.operationId` option.
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
services: {
operationId: true,
},
}
```
## v0.41.0 [Section titled “v0.41.0”](#v0410) ### Removed `postfixServices` [Section titled “Removed postfixServices”](#removed-postfixservices) This config option has been removed. You can now transform service names using the string pattern parameter.
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
services: {
name: 'myAwesome{{name}}Api',
},
}
```
### Removed `serviceResponse` [Section titled “Removed serviceResponse”](#removed-serviceresponse) This config option has been removed. You can now configure service responses using the `services.response` option.
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
services: {
response: 'body',
},
}
```
### Removed `useDateType` [Section titled “Removed useDateType”](#removed-usedatetype) This config option has been removed. You can now configure date type using the `types.dates` option.
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
type: {
dates: true,
},
}
```
## v0.40.0 [Section titled “v0.40.0”](#v0400) ### Renamed `models.gen.ts` file [Section titled “Renamed models.gen.ts file”](#renamed-modelsgents-file) `models.gen.ts` is now called `types.gen.ts`. If you use imports from `models.gen.ts`, you should be able to easily find and replace all instances.
```diff
-import type { Model } from 'client/models.gen';
+import type { Model } from 'client/types.gen';
```
### Renamed `exportModels` [Section titled “Renamed exportModels”](#renamed-exportmodels) This config option is now called `types`. ### PascalCase for types [Section titled “PascalCase for types”](#pascalcase-for-types) You can now choose to export types using the PascalCase naming convention.
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
types: {
name: 'PascalCase',
},
}
```
### Exported `enums.gen.ts` file [Section titled “Exported enums.gen.ts file”](#exported-enumsgents-file) Enums are now re-exported from the main `index.ts` file. ## v0.39.0 [Section titled “v0.39.0”](#v0390) ### Single `enums.gen.ts` file [Section titled “Single enums.gen.ts file”](#single-enumsgents-file) Enums are now exported from a separate file. If you use imports from `models.ts`, you can change them to `enums.gen.ts`.
```diff
-import { Enum } from 'client/models';
+import { Enum } from 'client/enums.gen';
```
### Renamed `models.ts` file [Section titled “Renamed models.ts file”](#renamed-modelsts-file) `models.ts` is now called `models.gen.ts`. If you use imports from `models.ts`, you should be able to easily find and replace all instances.
```diff
-import type { Model } from 'client/models';
+import type { Model } from 'client/models.gen';
```
### Renamed `schemas.ts` file [Section titled “Renamed schemas.ts file”](#renamed-schemasts-file) `schemas.ts` is now called `schemas.gen.ts`. If you use imports from `schemas.ts`, you should be able to easily find and replace all instances.
```diff
-import { $Schema } from 'client/schemas';
+import { $Schema } from 'client/schemas.gen';
```
### Renamed `services.ts` file [Section titled “Renamed services.ts file”](#renamed-servicests-file) `services.ts` is now called `services.gen.ts`. If you use imports from `services.ts`, you should be able to easily find and replace all instances.
```diff
-import { DefaultService } from 'client/services';
+import { DefaultService } from 'client/services.gen';
```
### Deprecated exports from `index.ts` [Section titled “Deprecated exports from index.ts”](#deprecated-exports-from-indexts) Until this release, `index.ts` file exported all generated artifacts. Starting from this release, enums are no longer exported from `index.ts`. Models, schemas, and services will continue to be exported from `index.ts` to avoid a huge migration lift, but we recommend migrating to import groups per artifact type.
```diff
-import { Enum, type Model, $Schema, DefaultService } from 'client';
+import { Enum } from 'client/enums.gen';
+import type { Model } from 'client/models.gen';
+import { $Schema } from 'client/schemas.gen';
+import { DefaultService } from 'client/services.gen';
```
### Prefer `unknown` [Section titled “Prefer unknown”](#prefer-unknown) Types that cannot be determined will now be generated as `unknown` instead of `any`. To dismiss any errors, you can cast your variables back to `any`, but we recommend updating your code to work with `unknown` types.
```js
const foo = bar as any
```
## v0.38.0 [Section titled “v0.38.0”](#v0380) ### Renamed `write` [Section titled “Renamed write”](#renamed-write) This config option is now called `dryRun` (file) or `--dry-run` (CLI). To restore existing functionality, invert the value, ie. `write: true` is `dryRun: false` and `write: false` is `dryRun: true`. ## v0.36.0 [Section titled “v0.36.0”](#v0360) ### JSON Schema 2020-12 [Section titled “JSON Schema 2020-12”](#json-schema-2020-12) Schemas are exported directly from OpenAPI specification. This means your schemas might change depending on which OpenAPI version you’re using. If this release caused a field to be removed, consult the JSON Schema documentation on how to obtain the same value from JSON Schema (e.g., [required properties](https://json-schema.org/understanding-json-schema/reference/object#required)). ### Renamed `exportSchemas` [Section titled “Renamed exportSchemas”](#renamed-exportschemas) This config option is now called `schemas`. ## v0.35.0 [Section titled “v0.35.0”](#v0350) ### Removed `postfixModels` [Section titled “Removed postfixModels”](#removed-postfixmodels) This config option has been removed. ## v0.34.0 [Section titled “v0.34.0”](#v0340) ### Single `services.ts` file [Section titled “Single services.ts file”](#single-servicests-file) Services are now exported from a single file. If you used imports from individual service files, these will need to be updated to refer to the single `services.ts` file. ## v0.31.1 [Section titled “v0.31.1”](#v0311) ### Merged enums options [Section titled “Merged enums options”](#merged-enums-options) `useLegacyEnums` config option is now `enums: 'typescript'` and existing `enums: true` option is now `enums: 'javascript'`. ## v0.31.0 [Section titled “v0.31.0”](#v0310) ### Single `models.ts` file [Section titled “Single models.ts file”](#single-modelsts-file) TypeScript interfaces are now exported from a single file. If you used imports from individual model files, these will need to be updated to refer to the single `models.ts` file. ### Single `schemas.ts` file [Section titled “Single schemas.ts file”](#single-schemasts-file) Schemas are now exported from a single file. If you used imports from individual schema files, these will need to be updated to refer to the single `schemas.ts` file. ## v0.27.38 [Section titled “v0.27.38”](#v02738) ### `useOptions: true` [Section titled “useOptions: true”](#useoptions-true) By default, generated clients will use a single object argument to pass values to API calls. This is a significant change from the previous default of unspecified array of arguments. If migrating your application in one go isn’t feasible, we recommend deprecating your old client and generating a new client.
```ts
import { DefaultService } from 'client/services'; // <-- old client with array arguments
import { DefaultService } from 'client_v2/services'; // <-- new client with options argument
```
This way, you can gradually switch over to the new syntax as you update parts of your code. Once you’ve removed all instances of `client` imports, you can safely delete the old `client` folder and find and replace all `client_v2` calls to `client`. ## v0.27.36 [Section titled “v0.27.36”](#v02736) ### `exportSchemas: true` [Section titled “exportSchemas: true”](#exportschemas-true) By default, we will create schemas from your OpenAPI specification. Use `exportSchemas: false` to preserve the old behavior. ## v0.27.32 [Section titled “v0.27.32”](#v02732) ### Renamed `Config` interface [Section titled “Renamed Config interface”](#renamed-config-interface) This interface is now called `UserConfig`. ## v0.27.29 [Section titled “v0.27.29”](#v02729) ### Renamed `openapi` CLI command [Section titled “Renamed openapi CLI command”](#renamed-openapi-cli-command) This command is now called `openapi-ts`. ## v0.27.26 [Section titled “v0.27.26”](#v02726) ### Removed `indent` [Section titled “Removed indent”](#removed-indent) This config option has been removed. Use a [code formatter](https://heyapi.dev/docs/openapi/typescript/configuration/output#post-process) to modify the generated files code style according to your preferences. ## v0.27.24 [Section titled “v0.27.24”](#v02724) ### Removed `useUnionTypes` [Section titled “Removed useUnionTypes”](#removed-useuniontypes) This config option has been removed. Generated types will behave the same as `useUnionTypes: true` before. ## OpenAPI TypeScript Codegen [Section titled “OpenAPI TypeScript Codegen”](#openapi-typescript-codegen) `@hey-api/openapi-ts` was originally forked from Ferdi Koomen’s [openapi-typescript-codegen](https://github.com/ferdikoomen/openapi-typescript-codegen). Therefore, we want you to be able to migrate your projects. Migration should be relatively straightforward if you follow the release notes on this page. Start on [v0.27.24](#v0-27-24) and scroll to the release you’re migrating to.
# Mocks
> Learn about mocking HTTP servers with @hey-api/openapi-ts.
Realistic mock data is an important component of every robust development process, testing strategy, and product presentation. ## Plugins [Section titled “Plugins”](#plugins) Hey API natively supports the following mocking frameworks. * [Chance](https://heyapi.dev/docs/openapi/typescript/plugins/chance) Vote * [Faker](https://heyapi.dev/docs/openapi/typescript/plugins/faker) Vote * [Falso](https://heyapi.dev/docs/openapi/typescript/plugins/falso) Vote * [MSW](https://heyapi.dev/docs/openapi/typescript/plugins/msw) Vote * [Nock](https://heyapi.dev/docs/openapi/typescript/plugins/nock) Vote * [Supertest](https://heyapi.dev/docs/openapi/typescript/plugins/supertest) Vote Don’t see your framework? Let us know by [opening an issue](https://github.com/hey-api/openapi-ts/issues). ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Output
> Learn about files generated with @hey-api/openapi-ts.
Every generated file in your output folder is created by a plugin. This page describes the default output, but similar logic applies to all plugins. ## Overview [Section titled “Overview”](#overview) If you use the default configuration, your [project](https://stackblitz.com/edit/hey-api-example?file=openapi-ts.config.ts,src%2Fclient%2Fschemas.gen.ts,src%2Fclient%2Fsdk.gen.ts,src%2Fclient%2Ftypes.gen.ts) might look like this. Your actual output depends on your Hey API configuration. It may contain a different number of files and their contents might differ. Let’s go through each file in the `src/client` folder and explain what it looks like, what it does, and how to use it. ## Client [Section titled “Client”](#client) `client.gen.ts` is generated by [client plugins](https://heyapi.dev/docs/openapi/typescript/clients). If you choose to generate SDKs (enabled by default), we use the Fetch client unless specified otherwise. client.gen.ts
```ts
import { createClient, createConfig } from './client';
export const client = createClient(createConfig());
```
The contents of this file are consumed by SDKs, but you can also import `client` in your application to perform additional configuration or send manual requests. ### Bundle [Section titled “Bundle”](#bundle) Client plugins provide their bundles inside `client` and `core` folders. The contents of these folders don’t depend on the provided input. Everything inside these folders serves as a scaffolding so the generated code can make HTTP requests. ## TypeScript [Section titled “TypeScript”](#typescript) You can learn more on the [TypeScript](https://heyapi.dev/docs/openapi/typescript/plugins/typescript) page. ## SDK [Section titled “SDK”](#sdk) You can learn more on the [SDK](https://heyapi.dev/docs/openapi/typescript/plugins/sdk) page. ## Entry File [Section titled “Entry File”](#entry-file) `index.ts` is not generated by any specific plugin. It’s meant for convenience and by default, it re-exports every artifact generated by default plugins (TypeScript and SDK). index.ts
```ts
export * from './sdk.gen';
export * from './types.gen';
```
### Disable entry file [Section titled “Disable entry file”](#disable-entry-file) We recommend importing artifacts from their respective files to avoid ambiguity, but we leave this choice up to you. index.ts
```ts
import type { Pet } from './client';
// or
import type { Pet } from './client/types.gen';
```
If you’re not importing artifacts from the entry file, you can skip generating it altogether by setting the `output.entryFile` option to `false`. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
entryFile: false,
path: 'src/client',
},
};
```
### Re-export artifacts [Section titled “Re-export artifacts”](#re-export-artifacts) You can choose which artifacts should be re-exported from the entry file using the `includeInEntry` option on any plugin. For example, we can re-export all [Zod](https://heyapi.dev/docs/openapi/typescript/plugins/zod) plugin artifacts by setting `includeInEntry` to `true`: * example index.ts
```ts
export {
zAddPetData,
zAddPetResponse,
zApiResponse,
zCategory,
// ...more exports
} from './zod.gen';
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
includeInEntry: true,
name: 'zod',
},
],
};
```
Or we can re-export only specific artifacts by providing a predicate function: * example index.ts
```ts
export { zTag } from './zod.gen';
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
includeInEntry: (symbol) => symbol.name === 'zTag',
name: 'zod',
},
],
};
```
## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# AdonisJS
> AdonisJS plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/2364) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 13](https://github.com/hey-api/openapi-ts/issues/2364) ### About [Section titled “About”](#about) [AdonisJS](https://adonisjs.com) is a TypeScript-first web framework for building web apps and API servers. It comes with support for testing, modern tooling, an ecosystem of official packages, and more.
# Ajv
> Ajv plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1476) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 21](https://github.com/hey-api/openapi-ts/issues/1476) ### About [Section titled “About”](#about) [Ajv](https://ajv.js.org) is the fastest JSON validator for Node.js and browser.
# Angular v19 Plugin
> Generate Angular v19 HTTP requests and resources from OpenAPI with the Angular plugin for openapi-ts. Fully compatible with validators, transformers, and all core features.
Beta [Leave feedback](https://github.com/hey-api/openapi-ts/issues) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) ### About [Section titled “About”](#about) [Angular](https://angular.dev/) is a web framework that empowers developers to build fast, reliable applications. The Angular plugin for Hey API generates HTTP requests and resources from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ### Collaborators [Section titled “Collaborators”](#collaborators) * [ Max Scopp](https://github.com/max-scopp) ## Features [Section titled “Features”](#features) * Angular v19 support * seamless integration with `@hey-api/openapi-ts` ecosystem * generate HTTP requests * generate HTTP resources * minimal learning curve thanks to extending the underlying technology ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@angular/common` to your plugins and you’ll be ready to generate Angular artifacts. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@angular/common',
],
};
```
## Output [Section titled “Output”](#output) The Angular plugin will generate the following artifacts, depending on the input specification. ## Requests [Section titled “Requests”](#requests) A single function is generated for each endpoint. It returns an [`HttpRequest`](https://v19.angular.dev/api/common/http/HttpRequest) result. * example common.gen.ts
```ts
export const addPetRequest = (options) =>
client.requestOptions({
method: 'POST',
responseStyle: 'data',
url: '/pet',
...options,
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@angular/common',
httpRequests: true,
},
],
};
```
## Resources [Section titled “Resources”](#resources) A single function is generated for each endpoint. It returns a result from [`httpResource`](https://v19.angular.dev/api/common/http/httpResource) call. * example common.gen.ts
```ts
export const addPetResource = (options) => httpResource(() => addPetRequest(options()));
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@angular/common',
httpResources: true,
},
],
};
```
## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@angular/common/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Angular v20 Plugin
> Generate Angular v20 HTTP requests and resources from OpenAPI with the Angular plugin for openapi-ts. Fully compatible with validators, transformers, and all core features.
Beta [Leave feedback](https://github.com/hey-api/openapi-ts/issues) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) ### About [Section titled “About”](#about) [Angular](https://angular.dev/) is a web framework that empowers developers to build fast, reliable applications. The Angular plugin for Hey API generates HTTP requests and resources from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ### Collaborators [Section titled “Collaborators”](#collaborators) * [ Max Scopp](https://github.com/max-scopp) ## Features [Section titled “Features”](#features) * Angular v20 support * seamless integration with `@hey-api/openapi-ts` ecosystem * generate HTTP requests * generate HTTP resources * minimal learning curve thanks to extending the underlying technology ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@angular/common` to your plugins and you’ll be ready to generate Angular artifacts. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@angular/common',
],
};
```
## Output [Section titled “Output”](#output) The Angular plugin will generate the following artifacts, depending on the input specification. ## Requests [Section titled “Requests”](#requests) A single function is generated for each endpoint. It returns an [`HttpRequest`](https://angular.dev/api/common/http/HttpRequest) result. * example common.gen.ts
```ts
export const addPetRequest = (options) =>
client.requestOptions({
method: 'POST',
responseStyle: 'data',
url: '/pet',
...options,
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@angular/common',
httpRequests: true,
},
],
};
```
## Resources [Section titled “Resources”](#resources) A single function is generated for each endpoint. It returns a result from [`httpResource`](https://angular.dev/api/common/http/httpResource) call. * example common.gen.ts
```ts
export const addPetResource = (options) => httpResource(() => addPetRequest(options()));
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@angular/common',
httpResources: true,
},
],
};
```
## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@angular/common/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Arktype
> Arktype plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1473) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 62](https://github.com/hey-api/openapi-ts/issues/1473) ### About [Section titled “About”](#about) [Arktype](https://arktype.io) is a TypeScript’s 1:1 validator, optimized from editor to runtime.
# Chance
> Chance plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/2497) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 3](https://github.com/hey-api/openapi-ts/issues/2497) ### About [Section titled “About”](#about) [Chance](https://chancejs.com/) is a minimalist generator of random strings, numbers, etc. to help reduce some monotony particularly while writing automated tests or anywhere else you need anything random.
# Resolvers
> Understand the concepts behind plugins.
Sometimes the default plugin behavior isn’t what you need or expect. Resolvers let you patch plugins in a safe and performant way, without forking or reimplementing core logic. Currently available for [TypeScript](https://heyapi.dev/docs/openapi/typescript/plugins/typescript), [Valibot](https://heyapi.dev/docs/openapi/typescript/plugins/valibot), and [Zod](https://heyapi.dev/docs/openapi/typescript/plugins/zod). ## Examples [Section titled “Examples”](#examples) This page demonstrates resolvers through a few common scenarios. 1. [Handle arbitrary schema formats](#example-1) 2. [Validate high precision numbers](#example-2) 3. [Replace default base](#example-3) 4. [Create permissive enums](#example-4) ## Terminology [Section titled “Terminology”](#terminology) Before we look at examples, let’s go through the resolvers API to help you understand how they work. Plugins that support resolvers expose them through the `~resolvers` option. Each resolver is a function that receives context and returns an implemented node (or patches existing ones). The resolver context will usually contain: * `$` - The node builder interface. Use it to build your custom logic. * `nodes` - Parts of the plugin logic. You can use these to avoid reimplementing the functionality, or replace them with custom implementation. * `plugin` - The plugin instance. You’ll most likely use it to register new symbols. * `symbols` - Frequently used symbols. These are effectively shorthands for commonly used `plugin.referenceSymbol()` calls. Other fields may include the current schema or relevant utilities. ## Example 1 [Section titled “Example 1”](#example-1) ### Handle arbitrary schema formats [Section titled “Handle arbitrary schema formats”](#handle-arbitrary-schema-formats) By default, the Valibot plugin may produce the following schemas for `date` and `date-time` strings. valibot.gen.ts
```js
export const vDates = v.object({
created: v.pipe(v.string(), v.isoDate()),
modified: v.pipe(v.string(), v.isoTimestamp()),
});
```
We can override this behavior by patching the `nodes.format` function only for strings with `date` or `date-time` formats. openapi-ts.config.ts
```js
{
name: 'valibot',
'~resolvers': {
string(ctx) {
const { $, schema, symbols } = ctx;
const { v } = symbols;
if (schema.format === 'date' || schema.format === 'date-time') {
ctx.nodes.format = () => $(v).attr('isoDateTime').call();
}
}
}
}
```
This applies custom logic with surgical precision, without affecting the rest of the default behavior. * after valibot.gen.ts
```js
export const vDates = v.object({
created: v.pipe(v.string(), v.isoDateTime()),
modified: v.pipe(v.string(), v.isoDateTime()),
});
```
* before valibot.gen.ts
```js
export const vDates = v.object({
created: v.pipe(v.string(), v.isoDate()),
modified: v.pipe(v.string(), v.isoTimestamp()),
});
```
## Example 2 [Section titled “Example 2”](#example-2) ### Validate high precision numbers [Section titled “Validate high precision numbers”](#validate-high-precision-numbers) Let’s say you’re dealing with very large or unsafe numbers. valibot.gen.ts
```js
export const vAmount = v.number();
```
In this case, you’ll want to use a third-party library to validate your values. We can use big.js to validate all numbers by replacing the whole resolver. openapi-ts.config.ts
```js
{
name: 'valibot',
'~resolvers': {
number(ctx) {
const { $, plugin, symbols } = ctx;
const { v } = symbols;
const big = plugin.symbolOnce('Big', {
external: 'big.js',
importKind: 'default',
});
return $(v).attr('instance').call(big);
}
}
}
```
We’re calling `plugin.symbolOnce()` to ensure we always use the same symbol reference. * after valibot.gen.ts
```js
import Big from 'big.js';
export const vAmount = v.instance(Big);
```
* before valibot.gen.ts
```js
export const vAmount = v.number();
```
## Example 3 [Section titled “Example 3”](#example-3) ### Replace default base [Section titled “Replace default base”](#replace-default-base) You might want to replace the default base schema, e.g., `v.object()`. valibot.gen.ts
```js
export const vUser = v.object({
age: v.number(),
});
```
Let’s say we want to interpret any schema without explicitly defined additional properties as a loose object. openapi-ts.config.ts
```js
{
name: 'valibot',
'~resolvers': {
object(ctx) {
const { $, symbols } = ctx;
const { v } = symbols;
const additional = ctx.nodes.additionalProperties(ctx);
if (additional === undefined) {
const shape = ctx.nodes.shape(ctx);
ctx.nodes.base = () => $(v).attr('looseObject').call(shape);
}
}
}
}
```
Above we demonstrate patching a node based on the result of another node. * after valibot.gen.ts
```js
export const vUser = v.looseObject({
age: v.number(),
});
```
* before valibot.gen.ts
```js
export const vUser = v.object({
age: v.number(),
});
```
## Example 4 [Section titled “Example 4”](#example-4) ### Create permissive enums [Section titled “Create permissive enums”](#create-permissive-enums) By default, enum schemas are strict and will reject unknown values. zod.gen.ts
```js
export const zStatus = z.enum(['active', 'inactive', 'pending']);
```
You might want to accept unknown enum values, for example when the API adds new values that haven’t been added to the spec yet. You can use the enum resolver to create a permissive union. openapi-ts.config.ts
```js
{
name: 'zod',
'~resolvers': {
enum(ctx) {
const { $, symbols } = ctx;
const { z } = symbols;
const { enumMembers, literalSchemas } = ctx.nodes.items(ctx);
if (!enumMembers.length || enumMembers.length !== literalSchemas.length) {
return;
}
const enumSchema = $(z).attr('enum').call($.array(...enumMembers));
return $(z).attr('union').call(
$.array(enumSchema, $(z).attr('string').call())
);
}
}
}
```
This resolver creates a union that accepts both the known enum values and any other string. * after zod.gen.ts
```js
export const zStatus = z.union([z.enum(['active', 'inactive', 'pending']), z.string()]);
```
* before zod.gen.ts
```js
export const zStatus = z.enum(['active', 'inactive', 'pending']);
```
## Feedback [Section titled “Feedback”](#feedback) We welcome feedback on the Resolvers API. [Open a GitHub issue](https://github.com/hey-api/openapi-ts/issues) to request support for additional plugins.
# Custom Plugin
> Learn how to create your own Hey API plugin.
Caution Plugin API is in development. The interface might change before it becomes stable. We encourage you to leave feedback on [GitHub](https://github.com/hey-api/openapi-ts/issues). You may need to write your own plugin if the available plugins do not suit your needs or you’re working on a proprietary use case. This can be easily achieved using the Plugin API. But don’t take our word for it – all Hey API plugins are written this way! ## File Structure [Section titled “File Structure”](#file-structure) We recommend following the design pattern of the native plugins. You can browse the code on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/packages/openapi-ts/src/plugins) as you follow this tutorial. First, create a `my-plugin` folder for your plugin files. Inside, create a barrel file `index.ts` exporting the plugin. index.ts
```ts
export { defaultConfig, defineConfig } from './config';
export type { MyPlugin } from './types';
```
## Types [Section titled “Types”](#types) `index.ts` references two files, so we need to create them. `types.ts` contains the TypeScript interface for your plugin options. types.ts
```ts
import type { DefinePlugin, Plugin } from '@hey-api/openapi-ts';
export type UserConfig = Plugin.Name<'my-plugin'> &
Plugin.Hooks &
Plugin.UserExports & {
/**
* User-configurable option for your plugin.
*/
user?: number | string | {
age?: number;
name?: string;
};
};
export type Config = Plugin.Name<'my-plugin'> &
Plugin.Hooks &
Plugin.Exports & {
/** Resolved option for your plugin. */
user: {
age: number;
name: string;
};
};
export type MyPlugin = DefinePlugin;
```
* `Plugin.Name` sets the plugin’s unique identifier. * `Plugin.Hooks` allows users to override plugin behavior through event hooks. For example, users can control how schemas are extracted or how symbols are routed to files. * `Plugin.Exports` add the `includeInEntry` option, which controls whether your plugin’s exports are re-exported from the output entry file. * `UserConfig` is what users write in their config file. `Config` is the fully resolved shape your handler receives. ## Configuration [Section titled “Configuration”](#configuration) `config.ts` defines the runtime configuration for your plugin, including how user input is resolved into `Config` and the `handler` function that generates output. config.ts
```ts
import { definePluginConfig } from '@hey-api/openapi-ts';
import { handler } from './plugin';
import type { MyPlugin } from './types';
export const defaultConfig: MyPlugin['Config'] = {
config: {
user: {
age: 42,
name: 'Stan Smith',
},
},
handler,
name: 'my-plugin',
};
/**
* Type helper for `my-plugin` plugin, returns {@link Plugin.Config} object
*/
export const defineConfig = definePluginConfig(defaultConfig);
```
The `config` table is a declarative resolution spec. Each field declares its default value and optional coercion rules. To allow users to set either `age` or `name` through the `user` field, we can add coercion rules to transform primitive values into the expected shape. * config config.ts
```ts
import { definePluginConfig } from '@hey-api/openapi-ts';
import { handler } from './plugin';
import type { MyPlugin } from './types';
export const defaultConfig: MyPlugin['Config'] = {
config: {
user: {
$coerce: {
number: (v) => ({ age: v }),
string: (v) => ({ name: v }),
},
age: 42,
name: 'Stan Smith',
},
},
handler,
name: 'my-plugin',
};
/**
* Type helper for `my-plugin` plugin, returns {@link Plugin.Config} object
*/
export const defineConfig = definePluginConfig(defaultConfig);
```
* input openapi-ts.config.ts
```js
import { defineConfig } from 'path/to/my-plugin';
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
defineConfig({
user: 'Joe Doe', // or number to set age
}),
],
};
```
* resolved
```ts
{
user: {
age: 42,
name: 'Joe Doe'
}
}
```
### Dependencies [Section titled “Dependencies”](#dependencies) Plugins can declare dependencies on other plugins. A dependency will always be included in the output, even if the user hasn’t explicitly added it to their `plugins` config. This is useful when your plugin’s output builds on another plugin’s types or symbols. config.ts
```ts
export const defaultConfig: MyPlugin['Config'] = {
config: { ... },
dependencies: ['@hey-api/typescript'],
handler,
name: 'my-plugin',
};
```
#### Resolving tags [Section titled “Resolving tags”](#resolving-tags) Some dependencies aren’t known at authoring time, such as which validator plugin the user has installed. Use `resolveTag` inside a `coerce()` call to look up the active plugin for a given tag at resolution time. In most cases, you’ll also want to declare a dependency on the field to ensure it’s included in the output. config.ts
```ts
import type { PluginContext } from '@hey-api/openapi-ts';
import { coerce } from '@hey-api/openapi-ts';
export const defaultConfig: MyPlugin['Config'] = {
config: {
$dependencies: ['validator'],
validator: coerce((value, context) => {
if (value === true || value === undefined) {
return (context as PluginContext).resolveTag('validator');
}
return value;
}),
},
dependencies: ['@hey-api/typescript'],
handler,
name: 'my-plugin',
};
```
## Handler [Section titled “Handler”](#handler) The `handler` function generates the actual output. We recommend implementing it in `plugin.ts`. plugin.ts
```ts
import { $ } from '@hey-api/openapi-ts';
import type { MyPlugin } from './types';
export const handler: MyPlugin['Handler'] = ({ plugin }) => {
plugin.forEach('operation', 'schema', (event) => {
if (event.type === 'operation') {
// do something with the operation
} else if (event.type === 'schema') {
// do something with the schema
}
});
// use the TypeScript DSL to build nodes
const symbolName = plugin.symbol('user');
const node = $.const(symbolName)
.export()
.assign($.literal(plugin.config.user.name));
plugin.node(node);
};
```
## Symbols [Section titled “Symbols”](#symbols) Symbols are a type-safe way to reference identifiers your plugin works with, whether from external libraries or your own generated output. Rather than querying or constructing identifiers manually, you declare them once and access them through `plugin.symbols` anywhere in your handler. Symbols are also visible to users customizing your plugin’s behavior. When a user provides hooks like `~resolvers`, they receive the `plugin` instance and can access `plugin.symbols` to reference your plugin’s identifiers directly. * symbols symbols.ts
```ts
import type { PluginInstance } from '@hey-api/openapi-ts';
export function myPluginSymbols(plugin: PluginInstance) {
return {
myLib: plugin.symbol('myLib', { external: 'my-lib' }),
};
}
export type MyPluginSymbols = ReturnType;
```
* types types.ts
```ts
import type { MyPluginSymbols } from './symbols';
/** ... */
export type MyPlugin = DefinePlugin;
```
* config config.ts
```ts
import { myPluginSymbols } from './symbols';
export const defaultConfig: MyPlugin['Config'] = {
config: { ... },
handler,
name: 'my-plugin',
symbols: myPluginSymbols,
};
```
* handler plugin.ts
```ts
export const handler: MyPlugin['Handler'] = ({ plugin }) => {
const { myLib } = plugin.symbols;
// use myLib as a typed reference when building nodes
};
```
## Usage [Section titled “Usage”](#usage) Once you’re satisfied with your plugin, register it in the [configuration](https://heyapi.dev/docs/openapi/typescript/configuration) file. openapi-ts.config.ts
```js
import { defineConfig } from 'path/to/my-plugin';
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
defineConfig(),
],
};
```
## Output [Section titled “Output”](#output) Putting all of this together will generate the following `my-plugin.gen.ts` file. my-plugin.gen.ts
```ts
export const user = 'Stan Smith';
```
Congratulations! You’ve successfully created your own plugin! 🎉 ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Elysia
> Elysia plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/2676) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [❤️ 32](https://github.com/hey-api/openapi-ts/issues/2676) ### About [Section titled “About”](#about) [Elysia](https://elysiajs.com/) is an ergonomic framework for humans. TypeScript with end-to-end type safety, type integrity, and exceptional developer experience. Supercharged by Bun.
# Express
> Express plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1484) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 58](https://github.com/hey-api/openapi-ts/issues/1484) ### About [Section titled “About”](#about) [Express](https://expressjs.com) is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
# Faker
> Faker plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1485) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 117](https://github.com/hey-api/openapi-ts/issues/1485) ### About [Section titled “About”](#about) [Faker](https://fakerjs.dev) is a popular library that generates fake (but reasonable) data that can be used for things such as unit testing, performance testing, building demos, and working without a completed backend.
# Falso
> Falso plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/2496) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) ### About [Section titled “About”](#about) [Falso](https://ngneat.github.io/falso/) creates massive amounts of fake data in the browser and NodeJS. Tree shakeable & fully typed.
# Fastify v5 Plugin
> Generate Fastify v5 route handlers from OpenAPI with the Fastify plugin for openapi-ts. Fully compatible with validators, transformers, and all core features.
Beta [Leave feedback](https://github.com/hey-api/openapi-ts/issues) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) ### About [Section titled “About”](#about) [Fastify](https://fastify.dev) is a fast and low overhead web framework for Node.js. The Fastify plugin for Hey API generates route handlers from your OpenAPI spec, fully compatible with all core features. ### Collaborators [Section titled “Collaborators”](#collaborators) * [ Jacob Cohen](https://github.com/jacobinu) ## Features [Section titled “Features”](#features) * Fastify v5 support * seamless integration with `@hey-api/openapi-ts` ecosystem * type-safe route handlers * minimal learning curve thanks to extending the underlying technology ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `fastify` to your plugins and you’ll be ready to generate Fastify artifacts. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'fastify',
],
};
```
## Output [Section titled “Output”](#output) The Fastify plugin will generate the following artifacts, depending on the input specification. ## Route Handlers [Section titled “Route Handlers”](#route-handlers) Route handlers are generated from all endpoints. The generated interface follows the naming convention of SDK functions. * example fastify.gen.ts
```ts
const fastify = Fastify();
const serviceHandlers: RouteHandlers = {
createPets(request, reply) {
reply.code(201).send();
},
listPets(request, reply) {
reply.code(200).send([]);
},
showPetById(request, reply) {
reply.code(200).send({
id: Number(request.params.petId),
name: 'Kitty',
});
},
};
fastify.register(glue, { serviceHandlers });
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'fastify',
],
};
```
## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/fastify/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples/openapi-ts-fastify).
# Hono
> Hono plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1483) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 106 ](https://github.com/hey-api/openapi-ts/issues/1483)[🎉 2 ](https://github.com/hey-api/openapi-ts/issues/1483)[🚀 30](https://github.com/hey-api/openapi-ts/issues/1483) ### About [Section titled “About”](#about) [Hono](https://hono.dev) is a small, simple, and ultrafast web framework built on Web Standards. It works on any JavaScript runtime: Cloudflare Workers, Fastly Compute, Deno, Bun, Vercel, Netlify, AWS Lambda, Lambda\@Edge, and Node.js.
# Joi
> Joi plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1477) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 3](https://github.com/hey-api/openapi-ts/issues/1477) ### About [Section titled “About”](#about) [Joi](https://joi.dev) is the most powerful schema description language and data validator for JavaScript.
# Koa
> Koa plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1482) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 6](https://github.com/hey-api/openapi-ts/issues/1482) ### About [Section titled “About”](#about) [Koa](https://koajs.com) is a new web framework designed by the team behind Express, which aims to be a smaller, more expressive, and more robust foundation for web applications and APIs.
# MSW
> MSW plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1486) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 302](https://github.com/hey-api/openapi-ts/issues/1486) ### About [Section titled “About”](#about) [MSW](https://mswjs.io) is an API mocking library that allows you to write client-agnostic mocks and reuse them across any frameworks, tools, and environments.
# NestJS v11 Plugin
> Generate NestJS v11 controller methods from OpenAPI with the NestJS plugin for openapi-ts. Fully compatible with validators, transformers, and all core features.
Beta [Leave feedback](https://github.com/hey-api/openapi-ts/issues) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) ### About [Section titled “About”](#about) [Nest](https://nestjs.com) is a progressive Node.js framework for building efficient, reliable and scalable server-side applications. The NestJS plugin for Hey API generates type-safe controller method signatures from your OpenAPI spec, fully compatible with all core features. ### Collaborators [Section titled “Collaborators”](#collaborators) * [ Yuri Mikhin](https://github.com/mikhin) ## Features [Section titled “Features”](#features) * NestJS v11 support * seamless integration with `@hey-api/openapi-ts` ecosystem * type-safe controller methods * minimal learning curve thanks to extending the underlying technology ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `nestjs` to your plugins and you’ll be ready to generate NestJS artifacts. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'nestjs',
],
};
```
## Output [Section titled “Output”](#output) The NestJS plugin will generate the following artifacts, depending on the input specification. ## Controller Methods [Section titled “Controller Methods”](#controller-methods) Operations are grouped by their first tag into separate types. * example nestjs.gen.ts
```ts
export type PetsControllerMethods = {
createPet: (body: CreatePetData['body']) => Promise;
listPets: (query?: ListPetsData['query']) => Promise;
showPetById: (path: ShowPetByIdData['path']) => Promise;
};
export type StoreControllerMethods = {
getInventory: () => Promise;
};
```
* usage pets.controller.ts
```ts
import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common';
import type { PetsControllerMethods } from '../client/nestjs.gen';
import type { CreatePetData, ListPetsData, ShowPetByIdData } from '../client/types.gen';
@Controller('pets')
export class PetsController implements Pick<
PetsControllerMethods,
'createPet' | 'listPets' | 'showPetById'
> {
@Post()
async createPet(@Body() body: CreatePetData['body']) {}
@Get()
async listPets(@Query() query?: ListPetsData['query']) {}
@Get(':petId')
async showPetById(@Param() path: ShowPetByIdData['path']) {}
}
```
## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/nestjs/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples/openapi-ts-nestjs).
# Nock
> Nock plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1487) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 10](https://github.com/hey-api/openapi-ts/issues/1487) ### About [Section titled “About”](#about) [Nock](https://github.com/nock/nock) is an HTTP server mocking and expectations library for Node.js.
# oRPC v1 Plugin
> Generate oRPC v1 contracts from OpenAPI with the oRPC plugin for openapi-ts. Fully compatible with validators, transformers, and all core features.
Beta [Leave feedback](https://github.com/hey-api/openapi-ts/issues) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) ### About [Section titled “About”](#about) [oRPC](https://orpc.dev) combines RPC with OpenAPI, allowing you to define and call remote or local procedures through a type-safe API while adhering to the OpenAPI specification. The oRPC plugin for Hey API generates contracts from your OpenAPI spec, fully compatible with all core features. ### Collaborators [Section titled “Collaborators”](#collaborators) * [ Stephen Zhou](https://github.com/hyoban) ## Features [Section titled “Features”](#features) * oRPC v1 support * seamless integration with `@hey-api/openapi-ts` ecosystem * generated contracts * minimal learning curve thanks to extending the underlying technology ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `orpc` to your plugins and you’ll be ready to generate oRPC artifacts. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'orpc',
],
};
```
## Output [Section titled “Output”](#output) The oRPC plugin will generate the following artifacts, depending on the input specification. ## Contracts [Section titled “Contracts”](#contracts) Contracts are generated from all endpoints. * example orpc.gen.ts
```ts
import { oc } from '@orpc/contract';
const addPet = oc.route({
description: 'Add a new pet to the store.',
inputStructure: 'detailed',
method: 'POST',
operationId: 'addPet',
path: '/pet',
summary: 'Add a new pet to the store.',
tags: ['pet'],
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'orpc',
],
};
```
### Validators [Section titled “Validators”](#validators) To enable schema validation, set `validator` to `zod` or one of the available [validator plugins](https://heyapi.dev/docs/openapi/typescript/validators). This will automatically add the selected plugin with its default configuration. For a more granular approach, manually add a validator plugin and set `validator` to the plugin name or `true` to automatically select a compatible plugin. Until you customize the validator plugin, both approaches will produce the same default output. * example orpc.gen.ts
```ts
import { oc } from '@orpc/contract';
import { vAddPetBody, vAddPetResponse } from './valibot.gen';
const addPet = oc
.route({
description: 'Add a new pet to the store.',
inputStructure: 'detailed',
method: 'POST',
operationId: 'addPet',
path: '/pet',
summary: 'Add a new pet to the store.',
tags: ['pet'],
})
.input(v.object({ body: vAddPetBody }))
.output(vAddPetResponse);
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'orpc',
validator: true, // or 'valibot'
},
{
name: 'valibot', // customize (optional)
// other options
},
],
};
```
You can choose to validate only inputs or outputs. * inputs openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'orpc',
validator: {
input: 'zod',
},
},
],
};
```
* outputs openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'orpc',
validator: {
output: 'zod',
},
},
],
};
```
Learn more about available validators on the [Validators](https://heyapi.dev/docs/openapi/typescript/validators) page. ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/orpc/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Pinia Colada v0 Plugin
> Generate Pinia Colada v0 functions and query keys from OpenAPI with the Pinia Colada plugin for openapi-ts. Fully compatible with validators, transformers, and all core features.
### About [Section titled “About”](#about) [Pinia Colada](https://pinia-colada.esm.dev) is the perfect companion to Pinia to handle async state management in your Vue applications. The Pinia Colada plugin for Hey API generates functions and query keys from your OpenAPI spec, fully compatible with SDKs, transformers, and all core features. ### Collaborators [Section titled “Collaborators”](#collaborators) * [ Dmitriy Brolnickij](https://github.com/brolnickij) * [ Josh Hemphill](https://github.com/josh-hemphill) * [ Sebastiaan Wouters](https://github.com/SebastiaanWouters) ## Features [Section titled “Features”](#features) * Pinia Colada v0 support * seamless integration with `@hey-api/openapi-ts` ecosystem * create query keys following the best practices * type-safe query options and mutation options * minimal learning curve thanks to extending the underlying technology ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@pinia/colada` to your plugins and you’ll be ready to generate Pinia Colada artifacts. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@pinia/colada',
],
};
```
## Output [Section titled “Output”](#output) The Pinia Colada plugin will generate the following artifacts, depending on the input specification. ## Queries [Section titled “Queries”](#queries) Queries are generated from [query operations](https://heyapi.dev/docs/openapi/typescript/configuration/parser#hooks-query-operations). The generated query functions follow the naming convention of SDK functions and by default append `Query`, e.g., `getPetByIdQuery()`. * example colada.gen.ts
```ts
const query = useQuery(getPetByIdQuery, () => ({
path: {
petId: 1,
},
}));
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@pinia/colada',
queryOptions: true,
},
],
};
```
You can customize the naming and casing pattern for `queryOptions` functions using the `.name` and `.case` options. ## Query Keys [Section titled “Query Keys”](#query-keys) Query keys contain normalized SDK function parameters and additional metadata. * example colada.gen.ts
```ts
const queryKey = [
{
_id: 'getPetById',
baseUrl: 'https://app.heyapi.dev',
path: {
petId: 1,
},
},
];
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@pinia/colada',
queryKeys: true,
},
],
};
```
### Tags [Section titled “Tags”](#tags) You can include operation tags in your query keys by setting `tags` to `true`. This will make query keys larger but provides better cache invalidation capabilities. * example colada.gen.ts
```ts
const key = [
{
_id: 'getPetById',
baseUrl: 'https://app.heyapi.dev',
path: {
petId: 1,
},
tags: ['pets', 'one', 'get'],
},
];
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@pinia/colada',
queryKeys: {
tags: true,
},
},
],
};
```
### Accessing Query Keys [Section titled “Accessing Query Keys”](#accessing-query-keys) If you have access to the result of query options function, you can get the query key from the `key` field. * example colada.gen.ts
```ts
const { key } = getPetByIdQuery({
path: {
petId: 1,
},
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@pinia/colada',
queryOptions: true,
},
],
};
```
Alternatively, you can access the same query key by calling query key functions. The generated query key functions follow the naming convention of SDK functions and by default append `QueryKey`, e.g., `getPetByIdQueryKey()`. * example colada.gen.ts
```ts
const key = getPetByIdQueryKey({
path: {
petId: 1,
},
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@pinia/colada',
queryKeys: true,
},
],
};
```
You can customize the naming and casing pattern for `queryKeys` functions using the `.name` and `.case` options. ## Mutations [Section titled “Mutations”](#mutations) Mutations are generated from [mutation operations](https://heyapi.dev/docs/openapi/typescript/configuration/parser#hooks-mutation-operations). The generated mutation functions follow the naming convention of SDK functions and by default append `Mutation`, e.g., `addPetMutation()`. * example colada.gen.ts
```ts
const addPet = useMutation({
...addPetMutation(),
onError: (error) => {
console.log(error);
},
});
addPet.mutate({
body: {
name: 'Kitty',
},
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@pinia/colada',
mutationOptions: true,
},
],
};
```
You can customize the naming and casing pattern for `mutationOptions` functions using the `.name` and `.case` options. ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@pinia/colada/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# JSON Schema
> Learn about files generated with @hey-api/openapi-ts.
Schemas are located in the `schemas.gen.ts` file. This file contains runtime schemas generated from your OpenAPI specification definitions located in `#/components/schemas`. If you’re using OpenAPI 3.1, your schemas are fully JSON Schema compliant and can be used with other tools supporting JSON Schema. ## Configuration [Section titled “Configuration”](#configuration) You can modify the contents of `schemas.gen.ts` by configuring the `@hey-api/schemas` plugin. Note that you must specify the default plugins to preserve the default output. * json openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@hey-api/schemas',
type: 'json',
},
],
};
```
* form openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@hey-api/schemas',
type: 'form',
},
],
};
```
* disabled openapi-ts.config.ts
```diff
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
-'@hey-api/schemas',
],
};
```
## Output [Section titled “Output”](#output) Below is an example output generated in the `type: 'form'` style. Disabling schemas will not generate the `schemas.gen.ts` file. schemas.gen.ts
```ts
export const PetSchema = {
required: ['name'],
properties: {
id: {
type: 'integer',
format: 'int64',
example: 10,
},
name: {
type: 'string',
example: 'doggie',
},
},
type: 'object',
} as const;
```
## Usage [Section titled “Usage”](#usage) A great use case for schemas is client-side form input validation. SomeComponent.ts
```ts
import { $Schema } from './client/schemas.gen';
const maxInputLength = $Schema.properties.text.maxLength;
if (userInput.length > maxInputLength) {
throw new Error(`Text length can't exceed ${maxInputLength} characters!`);
}
```
## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/schemas/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# SDK Plugin
> Generate SDKs from OpenAPI with the SDK plugin for openapi-ts. Fully compatible with validators, transformers, and all core features.
### About [Section titled “About”](#about) The SDK plugin generates a high-level, ergonomic API layer on top of the low-level HTTP client. It exposes typed functions or methods for each operation, with built-in auth handling, configurable request and response validation, and ready-to-use code examples. ## Features [Section titled “Features”](#features) * high-level SDK layer on top of the HTTP client * typed functions or methods per operation * built-in authentication handling * request and response validation * ready-to-use code examples ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@hey-api/sdk` to your plugins and you’ll be ready to generate SDK artifacts. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@hey-api/sdk',
],
};
```
## Output [Section titled “Output”](#output) The SDK plugin supports a wide range of configuration options. This guide focuses on two main SDK formats: tree-shakeable functions and instantiable classes, but you can apply the same concepts to create more advanced configurations. ## Flat [Section titled “Flat”](#flat) This is the default setting. Flat SDKs support tree-shaking, which can lead to a reduced bundle size. You select flat mode by setting `operations.strategy` to `flat`. * example sdk.gen.ts
```ts
import type { AddPetData } from './types.gen';
export const addPet = (options: Options) => {
/** ... */
};
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@hey-api/sdk',
operations: {
strategy: 'flat',
},
},
],
};
```
## Instance [Section titled “Instance”](#instance) Class SDKs do not support tree-shaking, which results in a larger bundle size, but you may prefer their syntax. You select class mode by setting `operations.strategy` to `single`. * example sdk.gen.ts
```ts
import type { AddPetData } from './types.gen';
export class Sdk extends HeyApiClient {
public addPet(options: Options) {
/** ... */
}
}
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@hey-api/sdk',
operations: {
strategy: 'single',
},
},
],
};
```
### Name [Section titled “Name”](#name) As shown above, by default our SDK class is called `Sdk`. The first thing you’ll likely want to do is change this to your preferred name, which you can do using `operation.containerName`. * example sdk.gen.ts
```ts
import { client } from './client.gen';
import type { AddPetData, AddPetErrors, AddPetResponses } from './types.gen';
export class PetStore extends HeyApiClient {
/** ... */
}
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@hey-api/sdk',
operations: {
containerName: 'PetStore',
strategy: 'single',
},
},
],
};
```
### Structure [Section titled “Structure”](#structure) While we try to infer the SDK structure from `operationId` fields, you’ll likely want to customize it further. You can do this using `operations.nesting`. Similar to the `operations.strategy` option, we provide a few presets. However, you gain the most control by providing your own function. To demonstrate the power of this feature, let’s nest a few endpoints inside a `Pet` class and rename them. Our original `addPet()` method will now become `pet.add()`. Notice that we use the built-in `OperationPath.fromOperationId()` helper to handle the remaining operations. * example sdk.gen.ts
```ts
import { client } from './client.gen';
import type { AddPetData, AddPetErrors, AddPetResponses } from './types.gen';
export class Pet extends HeyApiClient {
public add(options: Options) {
/** ... */
}
}
export class PetStore extends HeyApiClient {
get pet(): Pet {
/** ... */
}
}
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@hey-api/sdk',
operations: {
containerName: 'PetStore',
nesting(operation) {
if (operation.path === '/pet/{petId}' || operation.path === '/pet') {
return [
'pet',
operation.operationId?.replace(/Pet/, '') || operation.method.toLocaleLowerCase(),
];
}
return OperationPath.fromOperationId()(operation);
},
strategy: 'single',
},
},
],
};
```
## Auth [Section titled “Auth”](#auth) Most APIs require some form of authentication, which is why the SDK plugin provides built-in auth mechanisms by default. All you need to do is return the data from the `auth()` function, and the SDK will handle serialization and encoding for you. There are several ways to do this, for example on the client instance. * example sdk.gen.ts
```ts
import { client } from './client.gen';
client.setConfig({
auth() {
return '';
},
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
auth: true,
name: '@hey-api/sdk',
},
],
};
```
## Validators [Section titled “Validators”](#validators) Validating data at runtime comes with a performance cost, which is why it’s not enabled by default. To enable validation, set `validator` to `zod` or one of the available [validator plugins](https://heyapi.dev/docs/openapi/typescript/validators). This will automatically add the selected plugin with its default configuration. For a more granular approach, manually add a validator plugin and set `validator` to the plugin name or `true` to automatically select a compatible plugin. Until you customize the validator plugin, both approaches will produce the same default output. * example sdk.gen.ts
```ts
import * as v from 'valibot';
export const addPet = (options: Options) =>
(options.client ?? client).post({
requestValidator: async (data) =>
await v.parseAsync(vAddPetData, data),
responseValidator: async (data) =>
await v.parseAsync(vAddPetResponse, data),
/** ... */
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@hey-api/sdk',
validator: true, // or 'valibot'
},
{
name: 'valibot', // customize (optional)
// other options
},
],
};
```
You can choose to validate only requests or responses. * requests openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@hey-api/sdk',
validator: {
request: 'zod',
},
},
],
};
```
* responses openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@hey-api/sdk',
validator: {
response: 'zod',
},
},
],
};
```
Learn more about available validators on the [Validators](https://heyapi.dev/docs/openapi/typescript/validators) page. ## Transformers [Section titled “Transformers”](#transformers) Transformers work similarly to [validators](#validators), with two differences: transformation applies to responses only, and you use the `transformer` option instead of `validator`. * example sdk.gen.ts
```ts
import * as v from 'valibot';
export const addPet = (options: Options) =>
(options.client ?? client).post({
responseTransformer: async (data) =>
await v.parseAsync(vAddPetResponse, data),
/** ... */
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@hey-api/sdk',
transformer: true, // or 'valibot'
},
{
name: 'valibot', // customize (optional)
// other options
},
],
};
```
Learn more about available transformers on the [Validators](https://heyapi.dev/docs/openapi/typescript/validators) page. ## Code Examples [Section titled “Code Examples”](#code-examples) The SDK plugin can generate ready-to-use code examples for each operation, showing how to call the SDK methods with proper parameters and setup. Examples are not generated by default, but you can enable and customize them through the `examples` option. With the default settings, an example might look like this. * example
```ts
import { PetStore } from 'your-package';
await new PetStore().addPet();
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
examples: true,
name: '@hey-api/sdk',
operations: {
containerName: 'PetStore',
strategy: 'single',
},
},
],
};
```
### Module and Setup [Section titled “Module and Setup”](#module-and-setup) To make examples more practical, configure `moduleName` to specify the package from which users import your SDK. Next, set `setupName` to indicate how users should instantiate the SDK, typically only once per application. * example
```ts
import { PetStore } from '@petstore/client';
const client = new PetStore();
await client.addPet();
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
examples: {
moduleName: '@petstore/client',
setupName: 'client',
},
name: '@hey-api/sdk',
operations: {
containerName: 'PetStore',
strategy: 'single',
},
},
],
};
```
### Initialization [Section titled “Initialization”](#initialization) Often, your SDK needs to be instantiated with an API key or other configuration. In examples, `importSetup` lets you control how the SDK is initialized. * example
```ts
import { PetStore } from '@petstore/client';
const client = new PetStore({
apiKey: 'YOUR_API_KEY',
});
await client.addPet();
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
examples: {
importSetup: ({ $, node }) =>
$.new(
node.name,
$.object()
.pretty()
.prop('apiKey', $.literal('YOUR_API_KEY')),
),
moduleName: '@petstore/client',
setupName: 'client',
},
name: '@hey-api/sdk',
operations: {
containerName: 'PetStore',
strategy: 'single',
},
},
],
};
```
### Import Style [Section titled “Import Style”](#import-style) If you re-export the generated SDK from your own module, you can adjust `importName` and `importKind` to match your actual import style. * example
```ts
import CatStore from '@petstore/client';
const client = new CatStore({
apiKey: 'YOUR_API_KEY',
});
await client.addPet();
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
examples: {
importKind: 'default',
importName: 'CatStore',
importSetup: ({ $, node }) =>
$.new(
node.name,
$.object()
.pretty()
.prop('apiKey', $.literal('YOUR_API_KEY')),
),
moduleName: '@petstore/client',
setupName: 'client',
},
name: '@hey-api/sdk',
operations: {
containerName: 'PetStore',
strategy: 'single',
},
},
],
};
```
### Payload [Section titled “Payload”](#payload) You can customize the example request using the `payload` option. Requests can also be customized selectively. For example, we can provide a default payload only for the `addPet()` method. * example
```ts
import CatStore from '@petstore/client';
const client = new CatStore({
apiKey: 'YOUR_API_KEY',
});
await client.addPet({
petId: 1234,
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
examples: {
importKind: 'default',
importName: 'CatStore',
importSetup: ({ $, node }) =>
$.new(
node.name,
$.object()
.pretty()
.prop('apiKey', $.literal('YOUR_API_KEY')),
),
moduleName: '@petstore/client',
payload(operation, ctx) {
const { $ } = ctx;
if (operation.path === '/pet/{petId}' || operation.path === '/pet') {
return $.object().pretty().prop('petId', $.literal(1234));
}
},
setupName: 'client',
},
name: '@hey-api/sdk',
operations: {
containerName: 'PetStore',
strategy: 'single',
},
},
],
};
```
### Display [Section titled “Display”](#display) Enabling examples does not produce visible output on its own. Examples are written into the source specification and can be consumed by documentation tools such as [Scalar](https://kutt.to/skQUVd). To persist that specification, enable [Source](https://heyapi.dev/docs/openapi/typescript/configuration/output#source) generation. ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/sdk/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Superstruct
> Superstruct plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1489) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) ### About [Section titled “About”](#about) [Superstruct](https://docs.superstructjs.org) makes it easy to define interfaces and then validate JavaScript data against them.
# Supertest
> Supertest plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1488) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 9](https://github.com/hey-api/openapi-ts/issues/1488) ### About [Section titled “About”](#about) [Supertest](https://github.com/ladjs/supertest) is a super-agent driven library for testing node.js HTTP servers using a fluent API.
# SWR
> SWR plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1479) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 97](https://github.com/hey-api/openapi-ts/issues/1479) ### About [Section titled “About”](#about) [SWR](https://swr.vercel.app) is a strategy to first return the data from cache (stale), then send the fetch request (revalidate), and finally come with the up-to-date data.
# TanStack Query v5 Plugin
> Generate TanStack Query v5 functions and query keys from OpenAPI with the TanStack Query plugin for openapi-ts. Fully compatible with validators, transformers, and all core features.
### About [Section titled “About”](#about) [TanStack Query](https://tanstack.com/query) is a powerful asynchronous state management solution for TypeScript/JavaScript, React, Solid, Vue, Svelte, Angular, and Preact. The TanStack Query plugin for Hey API generates functions and query keys from your OpenAPI spec, fully compatible with SDKs, transformers, and all core features. ### Demo [Section titled “Demo”](#demo) Launch demo ## Features [Section titled “Features”](#features) * TanStack Query v5 support * seamless integration with `@hey-api/openapi-ts` ecosystem * create query keys following the best practices * type-safe query options, infinite query options, and mutation options * minimal learning curve thanks to extending the underlying technology ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add TanStack Query to your plugins and you’ll be ready to generate TanStack Query artifacts. 🎉 * react openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@tanstack/react-query',
],
};
```
* vue openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@tanstack/vue-query',
],
};
```
* angular openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@tanstack/angular-query-experimental',
],
};
```
* svelte openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@tanstack/svelte-query',
],
};
```
* solid openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@tanstack/solid-query',
],
};
```
* preact openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@tanstack/preact-query',
],
};
```
## Output [Section titled “Output”](#output) The TanStack Query plugin will generate the following artifacts, depending on the input specification. ## Queries [Section titled “Queries”](#queries) Queries are generated from [query operations](https://heyapi.dev/docs/openapi/typescript/configuration/parser#hooks-query-operations). The generated query functions follow the naming convention of SDK functions and by default append `Options`, e.g., `getPetByIdOptions()`. * example react-query.gen.ts
```ts
const query = useQuery({
...getPetByIdOptions({
path: {
petId: 1,
},
}),
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
queryOptions: true,
},
],
};
```
You can customize the naming and casing pattern for `queryOptions` functions using the `.name` and `.case` options. ### Meta [Section titled “Meta”](#meta) You can use the `meta` field to attach arbitrary information to a query. To generate metadata for `queryOptions`, provide a function to the `.meta` option. * example react-query.gen.ts
```ts
queryOptions({
// ...other fields
meta: {
id: 'getPetById',
},
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
queryOptions: {
meta: (operation) => ({ id: operation.id }),
},
},
],
};
```
## Query Keys [Section titled “Query Keys”](#query-keys) Query keys contain normalized SDK function parameters and additional metadata. * example react-query.gen.ts
```ts
const queryKey = [
{
_id: 'getPetById',
baseUrl: 'https://app.heyapi.dev',
path: {
petId: 1,
},
},
];
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
queryKeys: true,
},
],
};
```
### Tags [Section titled “Tags”](#tags) You can include operation tags in your query keys by setting `tags` to `true`. This will make query keys larger but provides better cache invalidation capabilities. * example react-query.gen.ts
```ts
const queryKey = [
{
_id: 'getPetById',
baseUrl: 'https://app.heyapi.dev',
path: {
petId: 1,
},
tags: ['pets', 'one', 'get'],
},
];
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
queryKeys: {
tags: true,
},
},
],
};
```
### Accessing Query Keys [Section titled “Accessing Query Keys”](#accessing-query-keys) If you have access to the result of query options function, you can get the query key from the `queryKey` field. * example react-query.gen.ts
```ts
const { queryKey } = getPetByIdOptions({
path: {
petId: 1,
},
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
queryOptions: true,
},
],
};
```
Alternatively, you can access the same query key by calling query key functions. The generated query key functions follow the naming convention of SDK functions and by default append `QueryKey`, e.g., `getPetByIdQueryKey()`. * example react-query.gen.ts
```ts
const queryKey = getPetByIdQueryKey({
path: {
petId: 1,
},
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
queryKeys: true,
},
],
};
```
You can customize the naming and casing pattern for `queryKeys` functions using the `.name` and `.case` options. ## Infinite Queries [Section titled “Infinite Queries”](#infinite-queries) Infinite queries are generated from [query operations](https://heyapi.dev/docs/openapi/typescript/configuration/parser#hooks-query-operations) if we detect a [pagination](https://heyapi.dev/docs/openapi/typescript/configuration/parser#pagination) parameter. The generated infinite query functions follow the naming convention of SDK functions and by default append `InfiniteOptions`, e.g., `getFooInfiniteOptions()`. * example react-query.gen.ts
```ts
const query = useInfiniteQuery({
...getFooInfiniteOptions({
path: {
fooId: 1,
},
}),
getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
initialPageParam: 0,
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
infiniteQueryOptions: true,
},
],
};
```
You can customize the naming and casing pattern for `infiniteQueryOptions` functions using the `.name` and `.case` options. ### Meta [Section titled “Meta”](#meta-1) You can use the `meta` field to attach arbitrary information to a query. To generate metadata for `infiniteQueryOptions`, provide a function to the `.meta` option. * example react-query.gen.ts
```ts
infiniteQueryOptions({
// ...other fields
meta: {
id: 'getPetById',
},
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
infiniteQueryOptions: {
meta: (operation) => ({ id: operation.id }),
},
},
],
};
```
## Infinite Query Keys [Section titled “Infinite Query Keys”](#infinite-query-keys) Infinite query keys contain normalized SDK function parameters and additional metadata. * example react-query.gen.ts
```ts
const queryKey = [
{
_id: 'getPetById',
_infinite: true,
baseUrl: 'https://app.heyapi.dev',
path: {
petId: 1,
},
},
];
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
infiniteQueryKeys: true,
},
],
};
```
### Tags [Section titled “Tags”](#tags-1) You can include operation tags in your infinite query keys by setting `tags` to `true`. This will make query keys larger but provides better cache invalidation capabilities. * example react-query.gen.ts
```ts
const queryKey = [
{
_id: 'getPetById',
_infinite: true,
baseUrl: 'https://app.heyapi.dev',
path: {
petId: 1,
},
tags: ['pets', 'one', 'get'],
},
];
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
infiniteQueryKeys: {
tags: true,
},
},
],
};
```
### Accessing Infinite Query Keys [Section titled “Accessing Infinite Query Keys”](#accessing-infinite-query-keys) If you have access to the result of infinite query options function, you can get the query key from the `queryKey` field. * example react-query.gen.ts
```ts
const { queryKey } = getPetByIdInfiniteOptions({
path: {
petId: 1,
},
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
infiniteQueryOptions: true,
},
],
};
```
Alternatively, you can access the same query key by calling query key functions. The generated query key functions follow the naming convention of SDK functions and by default append `InfiniteQueryKey`, e.g., `getPetByIdInfiniteQueryKey()`. * example react-query.gen.ts
```ts
const queryKey = getPetByIdInfiniteQueryKey({
path: {
petId: 1,
},
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
infiniteQueryKeys: true,
},
],
};
```
You can customize the naming and casing pattern for `infiniteQueryKeys` functions using the `.name` and `.case` options. ## Mutations [Section titled “Mutations”](#mutations) Mutations are generated from [mutation operations](https://heyapi.dev/docs/openapi/typescript/configuration/parser#hooks-mutation-operations). The generated mutation functions follow the naming convention of SDK functions and by default append `Mutation`, e.g., `addPetMutation()`. * example react-query.gen.ts
```ts
const addPet = useMutation({
...addPetMutation(),
onError: (error) => {
console.log(error);
},
});
addPet.mutate({
body: {
name: 'Kitty',
},
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
mutationOptions: true,
},
],
};
```
You can customize the naming and casing pattern for `mutationOptions` functions using the `.name` and `.case` options. ## Mutation Keys [Section titled “Mutation Keys”](#mutation-keys) Mutation keys contain normalized SDK function parameters and additional metadata. * example react-query.gen.ts
```ts
const mutationKey = [
{
_id: 'addPet',
baseUrl: 'https://app.heyapi.dev',
body: {
name: 'Kitty',
},
},
];
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
mutationKeys: true,
},
],
};
```
### Meta [Section titled “Meta”](#meta-2) You can use the `meta` field to attach arbitrary information to a mutation. To generate metadata for `mutationOptions`, provide a function to the `.meta` option. * example react-query.gen.ts
```ts
const mutationOptions = {
// ...other fields
meta: {
id: 'getPetById',
},
};
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: '@tanstack/react-query',
mutationOptions: {
meta: (operation) => ({ id: operation.id }),
},
},
],
};
```
## Reactivity [Section titled “Reactivity”](#reactivity) In Vue applications, you need to wrap the options functions in [`computed()`](https://vuejs.org/guide/essentials/computed) to make them reactive. Otherwise, TanStack Query won’t know it should execute the query when its dependencies change. * reactive react-query.gen.ts
```js
// ✅ Query will execute on `petId` change
const query = useQuery(
computed(() =>
getPetByIdOptions({
path: {
petId: petId.value,
},
}),
),
);
```
* static react-query.gen.ts
```js
// ❌ Query will execute only once
const query = useQuery(
getPetByIdOptions({
path: {
petId: petId.value,
},
}),
);
```
## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@tanstack/react-query/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# TanStack Start
> TanStack Start plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/3909) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 22](https://github.com/hey-api/openapi-ts/issues/3909) ### About [Section titled “About”](#about) [TanStack Start](https://tanstack.com/start) is a full-stack framework powered by TanStack Router for React and Solid.
# Transformers
> Learn about transforming data with @hey-api/openapi-ts.
JSON is the most commonly used data format in REST APIs. However, it does not map well to complex data types. For example, both regular strings and date strings become simple strings in JSON. One approach to this problem is using a [JSON superset](https://github.com/blitz-js/superjson). For most people, switching formats is not feasible. That’s why we provide the `@hey-api/transformers` plugin. ## Considerations [Section titled “Considerations”](#considerations) Before deciding whether transformers are right for you, let’s explain how they work. Transformers generate a runtime file, therefore they impact the bundle size. We generate a single transformer per operation response for the most efficient result, just like a human engineer would. ### Limitations [Section titled “Limitations”](#limitations) Transformers handle only the most common scenarios. Some of the known limitations are: * union types are not transformed (e.g., if you have multiple possible response shapes) * only types defined through `$ref` are transformed * error responses are not transformed If your data isn’t being transformed as expected, we encourage you to leave feedback on [GitHub](https://github.com/hey-api/openapi-ts/issues). ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@hey-api/transformers` to your plugins and you’ll be ready to generate transformers. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@hey-api/transformers',
],
};
```
## SDKs [Section titled “SDKs”](#sdks) To transform response data in your SDKs, set `transformer` to `true` on the SDK plugin. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@hey-api/transformers',
{
name: '@hey-api/sdk',
transformer: true,
},
],
};
```
## Dates [Section titled “Dates”](#dates) To convert date strings into `Date` objects, use the `dates` configuration option. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
dates: true,
name: '@hey-api/transformers',
},
],
};
```
This will generate types that use `Date` instead of `string` and appropriate transformers. ### Temporal [Section titled “Temporal”](#temporal) To use the [Temporal API](https://tc39.es/proposal-temporal/docs/) via [`temporal-polyfill`](https://github.com/fullcalendar/temporal-polyfill), set `dates` to `temporal`. * example transformers.gen.ts
```ts
import { Temporal } from 'temporal-polyfill';
import type { GetFooResponse } from './types.gen';
const quxSchemaResponseTransformer = (data: any) => {
if (data.baz) {
data.baz = Temporal.Instant.from(data.baz);
}
return data;
};
const bazSchemaResponseTransformer = (data: any) => {
data = quxSchemaResponseTransformer(data);
data.bar = Temporal.Instant.from(data.bar);
return data;
};
export const getFooResponseTransformer = async (data: any): Promise => {
data = bazSchemaResponseTransformer(data);
return data;
};
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
dates: 'temporal',
name: '@hey-api/transformers',
},
],
};
```
## BigInt [Section titled “BigInt”](#bigint) The `@hey-api/transformers` plugin will natively type all BigInts as `bigint` instead of `number`, which can affect arithmetic operations if your application previously used `number`. To force BigInts to be numbers, use the `bigInt` configuration option. openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
bigInt: true,
name: '@hey-api/transformers',
},
],
};
```
## Example [Section titled “Example”](#example) A generated response transformer might look something like this. Please note the example has been edited for brevity. * transformers.gen.ts transformers.gen.ts
```ts
import type { GetFooResponse } from './types.gen';
const quxSchemaResponseTransformer = (data: any) => {
if (data.baz) {
data.baz = new Date(data.baz);
}
return data;
};
const bazSchemaResponseTransformer = (data: any) => {
data = quxSchemaResponseTransformer(data);
data.bar = new Date(data.bar);
return data;
};
export const getFooResponseTransformer = async (data: any): Promise => {
data = bazSchemaResponseTransformer(data);
return data;
};
```
* types.gen.ts types.gen.ts
```ts
export type Baz = Qux & {
id: 'Baz';
} & {
foo: number;
bar: Date;
baz: 'foo' | 'bar' | 'baz';
qux: number;
};
export type Qux = {
foo: number;
bar: number;
baz?: Date;
id: string;
};
export type GetFooResponse = Baz;
```
## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/transformers/types.ts) interface.
# TypeBox
> TypeBox plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1475) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 37](https://github.com/hey-api/openapi-ts/issues/1475) ### About [Section titled “About”](#about) [TypeBox](https://github.com/sinclairzx81/typebox) is a JSON Schema type builder with static type resolution for TypeScript.
# TypeScript
> Learn about files generated with @hey-api/openapi-ts.
TypeScript interfaces are located in the `types.gen.ts` file. This is the only file that does not impact your bundle size and runtime performance. It will get discarded during build time, unless you configured to emit runtime [enums](#enums). ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `@hey-api/typescript` to your plugins and you’ll be ready to generate TypeScript artifacts. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'@hey-api/typescript',
],
};
```
## Output [Section titled “Output”](#output) The TypeScript plugin will generate the following artifacts, depending on the input specification. ## Requests [Section titled “Requests”](#requests) A single request type is generated for each endpoint. It may contain a request body, parameters, and headers. types.gen.ts
```ts
export type AddPetData = {
body: {
id?: number;
name: string;
};
path?: never;
query?: never;
url: '/pets';
};
```
You can customize the naming and casing pattern for `requests` types using the `.name` and `.case` options. ## Responses [Section titled “Responses”](#responses) A single type is generated for all endpoint’s responses. types.gen.ts
```ts
export type AddPetResponses = {
200: {
id?: number;
name: string;
};
};
export type AddPetResponse = AddPetResponses[keyof AddPetResponses];
```
You can customize the naming and casing pattern for `responses` types using the `.name` and `.case` options. ## Definitions [Section titled “Definitions”](#definitions) A type is generated for every reusable definition from your input. types.gen.ts
```ts
export type Pet = {
id?: number;
name: string;
};
```
You can customize the naming and casing pattern for `definitions` types using the `.name` and `.case` options. ## Enums [Section titled “Enums”](#enums) By default, `@hey-api/typescript` will emit enums only as types. You may want to generate runtime artifacts. A good use case is iterating through possible field values without manually typing arrays. To emit runtime enums, set `enums` to a valid option. * disabled openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
enums: false, // default
name: '@hey-api/typescript',
},
],
};
```
* javascript openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
enums: 'javascript',
name: '@hey-api/typescript',
},
],
};
```
* typescript openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
enums: 'typescript',
name: '@hey-api/typescript',
},
],
};
```
We recommend exporting enums as plain JavaScript objects. [TypeScript enums](https://www.typescriptlang.org/docs/handbook/enums.html) are not a type-level extension of JavaScript and pose [typing challenges](https://dev.to/ivanzm123/dont-use-enums-in-typescript-they-are-very-dangerous-57bh). ## Comments [Section titled “Comments”](#comments) By default, `@hey-api/typescript` will include comments in the generated code based on descriptions from your OpenAPI specification. If you want to reduce the size of your generated files or prefer cleaner output, you can disable comments. * enabled openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
comments: true, // default
name: '@hey-api/typescript',
},
],
};
```
* disabled openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
comments: false,
name: '@hey-api/typescript',
},
],
};
```
## Resolvers [Section titled “Resolvers”](#resolvers) You can further customize this plugin’s behavior using [resolvers](https://heyapi.dev/docs/openapi/typescript/plugins/concepts/resolvers). ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/typescript/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Valibot v1 Plugin
> Generate Valibot v1 schemas from OpenAPI with the Valibot plugin for openapi-ts. Fully compatible with validators, transformers, and all core features.
### About [Section titled “About”](#about) [Valibot](https://valibot.dev) is the open source schema library for TypeScript with bundle size, type safety and developer experience in mind. The Valibot plugin for Hey API generates schemas from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ## Features [Section titled “Features”](#features) * Valibot v1 support * seamless integration with `@hey-api/openapi-ts` ecosystem * Valibot schemas for requests, responses, and reusable definitions * minimal learning curve thanks to extending the underlying technology ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `valibot` to your plugins and you’ll be ready to generate Valibot artifacts. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'valibot',
],
};
```
### SDKs [Section titled “SDKs”](#sdks) Valibot can validate or transform data directly in your SDK. Set `validator` or `transformer` to `true` on the SDK plugin to enable it. * validator openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'valibot',
{
name: '@hey-api/sdk',
validator: true,
},
],
};
```
* transformer openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'valibot',
{
name: '@hey-api/sdk',
transformer: true,
},
],
};
```
The SDK page covers [validators](https://heyapi.dev/docs/openapi/typescript/plugins/sdk#validators) and [transformers](https://heyapi.dev/docs/openapi/typescript/plugins/sdk#transformers) in more detail. ## Output [Section titled “Output”](#output) The Valibot plugin will generate the following artifacts, depending on the input specification. ## Requests [Section titled “Requests”](#requests) A Valibot schema is generated for every request layer of each endpoint. * example valibot.gen.ts
```ts
const vDeletePetHeaders = v.object({
api_key: v.optional(v.string()),
});
const vDeletePetPath = v.object({
petId: v.number(),
});
const vDeletePetQuery = v.object({
additionalMetadata: v.string(),
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'valibot',
requests: true,
},
],
};
```
You can customize the naming and casing pattern for `requests` schemas using the `.name` and `.case` options. ## Responses [Section titled “Responses”](#responses) A single Valibot schema is generated for all endpoint’s responses. If the endpoint describes multiple responses, the generated schema is a union of all possible response shapes. * example valibot.gen.ts
```ts
const vResponse = v.union([
v.object({
foo: v.optional(v.string()),
}),
v.object({
bar: v.optional(v.number()),
}),
]);
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'valibot',
responses: true,
},
],
};
```
You can customize the naming and casing pattern for `responses` schemas using the `.name` and `.case` options. ## Definitions [Section titled “Definitions”](#definitions) A Valibot schema is generated for every reusable definition from your input. * example valibot.gen.ts
```ts
const vFoo = v.pipe(v.number(), v.integer());
const vBar = v.object({
bar: v.optional(v.array(v.pipe(v.number(), v.integer()))),
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'valibot',
definitions: true,
},
],
};
```
You can customize the naming and casing pattern for `definitions` schemas using the `.name` and `.case` options. ## Metadata [Section titled “Metadata”](#metadata) It’s often useful to associate a schema with some additional [metadata](https://valibot.dev/api/metadata/) for documentation, code generation, AI structured outputs, form validation, and other purposes. You can set `metadata` to `true` to attach descriptions to schemas when available. * example valibot.gen.ts
```ts
export const vFoo = v.pipe(
v.string(),
v.metadata({
description: 'Additional metadata',
}),
);
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'valibot',
metadata: true,
},
],
};
```
For more control over metadata, you can provide your own function. It receives the source `schema`, the target `node` object, and the `$` builder for populating metadata. * example valibot.gen.ts
```ts
export const vFoo = v.pipe(
v.string(),
v.metadata({
hasTitle: false,
createdAt: 1735732800000,
}),
);
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'valibot',
metadata({ $, node, schema }) {
node.prop('hasTitle', $.literal(Boolean(schema.title)));
node.prop('createdAt', $.literal(Date.now()));
},
},
],
};
```
## Resolvers [Section titled “Resolvers”](#resolvers) You can further customize this plugin’s behavior using [resolvers](https://heyapi.dev/docs/openapi/typescript/plugins/concepts/resolvers). ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/valibot/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Yup
> Yup plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1478) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 32](https://github.com/hey-api/openapi-ts/issues/1478) ### About [Section titled “About”](#about) [Yup](https://github.com/jquense/yup) is a schema builder for runtime value parsing and validation.
# Zod Mini Plugin
> Generate Zod Mini schemas from OpenAPI with the Zod plugin for openapi-ts. Fully compatible with validators, transformers, and all core features.
### About [Section titled “About”](#about) [Zod](https://zod.dev) is a TypeScript-first schema validation library with static type inference. The Zod plugin for Hey API generates schemas from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ## Features [Section titled “Features”](#features) * Zod Mini support * seamless integration with `@hey-api/openapi-ts` ecosystem * Zod schemas for requests, responses, and reusable definitions * minimal learning curve thanks to extending the underlying technology ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `zod` to your plugins and you’ll be ready to generate Zod artifacts. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 'mini',
},
],
};
```
### SDKs [Section titled “SDKs”](#sdks) Zod can validate or transform data directly in your SDK. Set `validator` or `transformer` to `true` on the SDK plugin to enable it. * validator openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 'mini',
},
{
name: '@hey-api/sdk',
validator: true,
},
],
};
```
* transformer openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 'mini',
},
{
name: '@hey-api/sdk',
transformer: true,
},
],
};
```
The SDK page covers [validators](https://heyapi.dev/docs/openapi/typescript/plugins/sdk#validators) and [transformers](https://heyapi.dev/docs/openapi/typescript/plugins/sdk#transformers) in more detail. ## Output [Section titled “Output”](#output) The Zod plugin will generate the following artifacts, depending on the input specification. ## Requests [Section titled “Requests”](#requests) A Zod schema is generated for every request layer of each endpoint. * example zod.gen.ts
```ts
const zDeletePetHeaders = z.object({
api_key: z.optional(z.string()),
});
const zDeletePetPath = z.object({
petId: z.number(),
});
const zDeletePetQuery = z.object({
additionalMetadata: z.string(),
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 'mini',
requests: true,
},
],
};
```
You can customize the naming and casing pattern for `requests` schemas using the `.name` and `.case` options. ## Responses [Section titled “Responses”](#responses) A single Zod schema is generated for all endpoint’s responses. If the endpoint describes multiple responses, the generated schema is a union of all possible response shapes. * example zod.gen.ts
```ts
const zResponse = z.union([
z.object({
foo: z.optional(z.string()),
}),
z.object({
bar: z.optional(z.number()),
}),
]);
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 'mini',
responses: true,
},
],
};
```
You can customize the naming and casing pattern for `responses` schemas using the `.name` and `.case` options. ## Definitions [Section titled “Definitions”](#definitions) A Zod schema is generated for every reusable definition from your input. * example zod.gen.ts
```ts
const zFoo = z.int();
const zBar = z.object({
bar: z.optional(z.array(z.int())),
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 'mini',
definitions: true,
},
],
};
```
You can customize the naming and casing pattern for `definitions` schemas using the `.name` and `.case` options. ## ISO Datetimes [Section titled “ISO Datetimes”](#iso-datetimes) By default, values without a timezone or with a timezone offset are not allowed in the `z.iso.datetime()` method. ### Timezone offsets [Section titled “Timezone offsets”](#timezone-offsets) You can allow values with timezone offsets by setting `dates.offset` to `true`. * example zod.gen.ts
```ts
export const zFoo = z.iso.datetime({ offset: true });
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 'mini',
dates: {
offset: true,
},
},
],
};
```
### Local times [Section titled “Local times”](#local-times) You can allow values without a timezone by setting `dates.local` to `true`. * example zod.gen.ts
```ts
export const zFoo = z.iso.datetime({ local: true });
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 'mini',
dates: {
local: true,
},
},
],
};
```
## Metadata [Section titled “Metadata”](#metadata) It’s often useful to associate a schema with some additional [metadata](https://zod.dev/metadata) for documentation, code generation, AI structured outputs, form validation, and other purposes. You can set `metadata` to `true` to attach descriptions to schemas when available. * example zod.gen.ts
```ts
export const zFoo = z.string().register(z.globalRegistry, {
description: 'Additional metadata',
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 'mini',
metadata: true,
},
],
};
```
For more control over metadata, you can provide your own function. It receives the source `schema`, the target `node` object, and the `$` builder for populating metadata. * example zod.gen.ts
```ts
export const zFoo = z.string().register(z.globalRegistry, {
hasTitle: true,
createdAt: 1735732800000,
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 'mini',
metadata({ $, node, schema }) {
node.prop('hasTitle', $.literal(Boolean(schema.title)));
node.prop('createdAt', $.literal(Date.now()));
},
},
],
};
```
## Types [Section titled “Types”](#types) In addition to Zod schemas, you can generate schema-specific types. These can be generated for all schemas or for specific resources. * example zod.gen.ts
```ts
export type ResponseZodType = z.infer;
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 'mini',
types: {
infer: false, // by default, no `z.infer` types
},
responses: {
types: {
infer: true, // `z.infer` types only for response schemas
},
},
},
],
};
```
You can customize the naming and casing pattern for schema-specific `types` using the `.name` and `.case` options. ## Resolvers [Section titled “Resolvers”](#resolvers) You can further customize this plugin’s behavior using [resolvers](https://heyapi.dev/docs/openapi/typescript/plugins/concepts/resolvers). ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/zod/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Zod v3 Plugin
> Generate Zod v3 schemas from OpenAPI with the Zod plugin for openapi-ts. Fully compatible with validators, transformers, and all core features.
### About [Section titled “About”](#about) [Zod](https://v3.zod.dev/) is a TypeScript-first schema validation library with static type inference. The Zod plugin for Hey API generates schemas from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ## Features [Section titled “Features”](#features) * Zod v3 support * seamless integration with `@hey-api/openapi-ts` ecosystem * Zod schemas for requests, responses, and reusable definitions * minimal learning curve thanks to extending the underlying technology ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `zod` to your plugins and you’ll be ready to generate Zod artifacts. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 3,
},
],
};
```
### SDKs [Section titled “SDKs”](#sdks) Zod can validate or transform data directly in your SDK. Set `validator` or `transformer` to `true` on the SDK plugin to enable it. * validator openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 3,
},
{
name: '@hey-api/sdk',
validator: true,
},
],
};
```
* transformer openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 3,
},
{
name: '@hey-api/sdk',
transformer: true,
},
],
};
```
The SDK page covers [validators](https://heyapi.dev/docs/openapi/typescript/plugins/sdk#validators) and [transformers](https://heyapi.dev/docs/openapi/typescript/plugins/sdk#transformers) in more detail. ## Output [Section titled “Output”](#output) The Zod plugin will generate the following artifacts, depending on the input specification. ## Requests [Section titled “Requests”](#requests) A Zod schema is generated for every request layer of each endpoint. * example zod.gen.ts
```ts
const zDeletePetHeaders = z.object({
api_key: z.string().optional(),
});
const zDeletePetPath = z.object({
petId: z.number(),
});
const zDeletePetQuery = z.object({
additionalMetadata: z.string(),
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 3,
requests: true,
},
],
};
```
You can customize the naming and casing pattern for `requests` schemas using the `.name` and `.case` options. ## Responses [Section titled “Responses”](#responses) A single Zod schema is generated for all endpoint’s responses. If the endpoint describes multiple responses, the generated schema is a union of all possible response shapes. * example zod.gen.ts
```ts
const zResponse = z.union([
z.object({
foo: z.string().optional(),
}),
z.object({
bar: z.number().optional(),
}),
]);
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 3,
responses: true,
},
],
};
```
You can customize the naming and casing pattern for `responses` schemas using the `.name` and `.case` options. ## Definitions [Section titled “Definitions”](#definitions) A Zod schema is generated for every reusable definition from your input. * example zod.gen.ts
```ts
const zFoo = z.number().int();
const zBar = z.object({
bar: z.array(z.number().int()).optional(),
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 3,
definitions: true,
},
],
};
```
You can customize the naming and casing pattern for `definitions` schemas using the `.name` and `.case` options. ## ISO Datetimes [Section titled “ISO Datetimes”](#iso-datetimes) By default, values without a timezone or with a timezone offset are not allowed in the `z.string().datetime()` method. ### Timezone offsets [Section titled “Timezone offsets”](#timezone-offsets) You can allow values with timezone offsets by setting `dates.offset` to `true`. * example zod.gen.ts
```ts
export const zFoo = z.string().datetime({ offset: true });
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 3,
dates: {
offset: true,
},
},
],
};
```
### Local times [Section titled “Local times”](#local-times) You can allow values without a timezone by setting `dates.local` to `true`. * example zod.gen.ts
```ts
export const zFoo = z.string().datetime({ local: true });
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 3,
dates: {
local: true,
},
},
],
};
```
## Metadata [Section titled “Metadata”](#metadata) It’s often useful to associate a schema with some additional [metadata](https://v3.zod.dev/?id=describe) for documentation, code generation, AI structured outputs, form validation, and other purposes. If this is your use case, you can set `metadata` to `true` to generate additional metadata about schemas. * example zod.gen.ts
```ts
export const zFoo = z.string().describe('Additional metadata');
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 3,
metadata: true,
},
],
};
```
## Types [Section titled “Types”](#types) In addition to Zod schemas, you can generate schema-specific types. These can be generated for all schemas or for specific resources. * example zod.gen.ts
```ts
export type ResponseZodType = z.infer;
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
compatibilityVersion: 3,
types: {
infer: false, // by default, no `z.infer` types
},
responses: {
types: {
infer: true, // `z.infer` types only for response schemas
},
},
},
],
};
```
You can customize the naming and casing pattern for schema-specific `types` using the `.name` and `.case` options. ## Resolvers [Section titled “Resolvers”](#resolvers) You can further customize this plugin’s behavior using [resolvers](https://heyapi.dev/docs/openapi/typescript/plugins/concepts/resolvers). ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/zod/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Zod v4 Plugin
> Generate Zod v4 schemas from OpenAPI with the Zod plugin for openapi-ts. Fully compatible with validators, transformers, and all core features.
### About [Section titled “About”](#about) [Zod](https://zod.dev) is a TypeScript-first schema validation library with static type inference. The Zod plugin for Hey API generates schemas from your OpenAPI spec, fully compatible with validators, transformers, and all core features. ## Features [Section titled “Features”](#features) * Zod v4 support * seamless integration with `@hey-api/openapi-ts` ecosystem * Zod schemas for requests, responses, and reusable definitions * minimal learning curve thanks to extending the underlying technology ## Installation [Section titled “Installation”](#installation) In your [configuration](https://heyapi.dev/docs/openapi/typescript/get-started), add `zod` to your plugins and you’ll be ready to generate Zod artifacts. 🎉 openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'zod',
],
};
```
### SDKs [Section titled “SDKs”](#sdks) Zod can validate or transform data directly in your SDK. Set `validator` or `transformer` to `true` on the SDK plugin to enable it. * validator openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'zod',
{
name: '@hey-api/sdk',
validator: true,
},
],
};
```
* transformer openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
'zod',
{
name: '@hey-api/sdk',
transformer: true,
},
],
};
```
The SDK page covers [validators](https://heyapi.dev/docs/openapi/typescript/plugins/sdk#validators) and [transformers](https://heyapi.dev/docs/openapi/typescript/plugins/sdk#transformers) in more detail. ## Output [Section titled “Output”](#output) The Zod plugin will generate the following artifacts, depending on the input specification. ## Requests [Section titled “Requests”](#requests) A Zod schema is generated for every request layer of each endpoint. * example zod.gen.ts
```ts
const zDeletePetHeaders = z.object({
api_key: z.string().optional(),
});
const zDeletePetPath = z.object({
petId: z.number(),
});
const zDeletePetQuery = z.object({
additionalMetadata: z.string(),
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
requests: true,
},
],
};
```
You can customize the naming and casing pattern for `requests` schemas using the `.name` and `.case` options. ## Responses [Section titled “Responses”](#responses) A single Zod schema is generated for all endpoint’s responses. If the endpoint describes multiple responses, the generated schema is a union of all possible response shapes. * example zod.gen.ts
```ts
const zResponse = z.union([
z.object({
foo: z.optional(z.string()),
}),
z.object({
bar: z.optional(z.number()),
}),
]);
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
responses: true,
},
],
};
```
You can customize the naming and casing pattern for `responses` schemas using the `.name` and `.case` options. ## Definitions [Section titled “Definitions”](#definitions) A Zod schema is generated for every reusable definition from your input. * example zod.gen.ts
```ts
const zFoo = z.int();
const zBar = z.object({
bar: z.optional(z.array(z.int())),
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
definitions: true,
},
],
};
```
You can customize the naming and casing pattern for `definitions` schemas using the `.name` and `.case` options. ## ISO Datetimes [Section titled “ISO Datetimes”](#iso-datetimes) By default, values without a timezone or with a timezone offset are not allowed in the `z.iso.datetime()` method. ### Timezone offsets [Section titled “Timezone offsets”](#timezone-offsets) You can allow values with timezone offsets by setting `dates.offset` to `true`. * example zod.gen.ts
```ts
export const zFoo = z.iso.datetime({ offset: true });
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
dates: {
offset: true,
},
},
],
};
```
### Local times [Section titled “Local times”](#local-times) You can allow values without a timezone by setting `dates.local` to `true`. * example zod.gen.ts
```ts
export const zFoo = z.iso.datetime({ local: true });
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
dates: {
local: true,
},
},
],
};
```
## Metadata [Section titled “Metadata”](#metadata) It’s often useful to associate a schema with some additional [metadata](https://zod.dev/metadata) for documentation, code generation, AI structured outputs, form validation, and other purposes. You can set `metadata` to `true` to attach descriptions to schemas when available. * example zod.gen.ts
```ts
export const zFoo = z.string().register(z.globalRegistry, {
description: 'Additional metadata',
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
metadata: true,
},
],
};
```
For more control over metadata, you can provide your own function. It receives the source `schema`, the target `node` object, and the `$` builder for populating metadata. * example zod.gen.ts
```ts
export const zFoo = z.string().register(z.globalRegistry, {
hasTitle: true,
createdAt: 1735732800000,
});
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
metadata({ $, node, schema }) {
node.prop('hasTitle', $.literal(Boolean(schema.title)));
node.prop('createdAt', $.literal(Date.now()));
},
},
],
};
```
## Types [Section titled “Types”](#types) In addition to Zod schemas, you can generate schema-specific types. These can be generated for all schemas or for specific resources. * example zod.gen.ts
```ts
export type ResponseZodType = z.infer;
```
* config openapi-ts.config.ts
```js
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
plugins: [
// ...other plugins
{
name: 'zod',
types: {
infer: false, // by default, no `z.infer` types
},
responses: {
types: {
infer: true, // `z.infer` types only for response schemas
},
},
},
],
};
```
You can customize the naming and casing pattern for schema-specific `types` using the `.name` and `.case` options. ## Resolvers [Section titled “Resolvers”](#resolvers) You can further customize this plugin’s behavior using [resolvers](https://heyapi.dev/docs/openapi/typescript/plugins/concepts/resolvers). ## API [Section titled “API”](#api) You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/zod/types.ts) interface. ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Zustand
> Zustand plugin for Hey API. Compatible with all our features.
Planned [Vote to prioritize](https://github.com/hey-api/openapi-ts/issues/1480) · [Contribute](https://heyapi.dev/docs/openapi/typescript/community/contributing) [👍 72 ](https://github.com/hey-api/openapi-ts/issues/1480)[🚀 21](https://github.com/hey-api/openapi-ts/issues/1480) ### About [Section titled “About”](#about) [Zustand](https://zustand-demo.pmnd.rs) is a small, fast, and scalable bearbones state management solution.
# State Management
> Learn about handling state with @hey-api/openapi-ts.
Any reasonably large application will have to deal with state management at some point. State-related code is often one of the biggest boilerplates in your codebase. Well, at least until you start using our state management plugins. ## Plugins [Section titled “Plugins”](#plugins) Hey API natively supports the following state managers. * [Pinia Colada](https://heyapi.dev/docs/openapi/typescript/plugins/pinia-colada) * [TanStack Query](https://heyapi.dev/docs/openapi/typescript/plugins/tanstack-query) * [SWR](https://heyapi.dev/docs/openapi/typescript/plugins/swr) Vote * [Zustand](https://heyapi.dev/docs/openapi/typescript/plugins/zustand) Vote Don’t see your state manager? Let us know by [opening an issue](https://github.com/hey-api/openapi-ts/issues). ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Validators
> Learn about validating and transforming data with @hey-api/openapi-ts.
There are times when you cannot blindly trust the server to return the correct data. You might be working on a critical application where any mistakes would be costly, or you’re simply dealing with a legacy or undocumented system. Validator plugins generate schemas from your input. You can connect them to your client as [validators](https://heyapi.dev/docs/openapi/typescript/plugins/sdk#validators) or [transformers](https://heyapi.dev/docs/openapi/typescript/plugins/sdk#transformers) via the SDK plugin. ## Features [Section titled “Features”](#features) * seamless integration with `@hey-api/openapi-ts` ecosystem * schemas for requests, responses, and reusable definitions * static type inference from schemas * tree-shakeable output ## Plugins [Section titled “Plugins”](#plugins) Hey API natively supports the following validators. * [Valibot](https://heyapi.dev/docs/openapi/typescript/plugins/valibot) * [Zod](https://heyapi.dev/docs/openapi/typescript/plugins/zod) * [Ajv](https://heyapi.dev/docs/openapi/typescript/plugins/ajv) Vote * [Arktype](https://heyapi.dev/docs/openapi/typescript/plugins/arktype) Vote * [Joi](https://heyapi.dev/docs/openapi/typescript/plugins/joi) Vote * [TypeBox](https://heyapi.dev/docs/openapi/typescript/plugins/typebox) Vote * [Yup](https://heyapi.dev/docs/openapi/typescript/plugins/yup) Vote Don’t see your validator? Let us know by [opening an issue](https://github.com/hey-api/openapi-ts/issues). ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Web Frameworks
> Learn about generating web framework code with @hey-api/openapi-ts.
There are two approaches to developing APIs: code-first, where you start with the code, or spec-first, where you begin with the specification. If you use the latter, you can ensure your APIs adhere to the specification with our web framework plugins. ## Plugins [Section titled “Plugins”](#plugins) Hey API natively supports the following frameworks. * [Angular](https://heyapi.dev/docs/openapi/typescript/plugins/angular) * [Fastify](https://heyapi.dev/docs/openapi/typescript/plugins/fastify) * [Nest](https://heyapi.dev/docs/openapi/typescript/plugins/nest) * [oRPC](https://heyapi.dev/docs/openapi/typescript/plugins/orpc) * [Adonis](https://heyapi.dev/docs/openapi/typescript/plugins/adonis) Vote * [Elysia](https://heyapi.dev/docs/openapi/typescript/plugins/elysia) Vote * [Express](https://heyapi.dev/docs/openapi/typescript/plugins/express) Vote * [Hono](https://heyapi.dev/docs/openapi/typescript/plugins/hono) Vote * [Koa](https://heyapi.dev/docs/openapi/typescript/plugins/koa) Vote * [TanStack Start](https://heyapi.dev/docs/openapi/typescript/plugins/tanstack-start) Vote Don’t see your framework? Let us know by [opening an issue](https://github.com/hey-api/openapi-ts/issues). ## Examples You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
# Sponsors
> Fuel the future of API tooling.
Open source Fuel the future of\ API tooling. ============ The open source API tooling standard. Built to last, not to exit. Your sponsorship funds full-time development and keeps the project independent. 3M weekly downloads 4.9K GitHub stars 1 maintainer Why sponsor Elite audience The best engineers use the best tools. Your brand in front of developers other tools don't reach. Contextual endorsement Where your product is relevant, we say so. Sponsors are woven into the content developers are already reading. Shape the roadmap Gold and above sponsors get their use cases prioritized. Your priorities become our priorities. Evergreen attribution Listed in every changelog and release note. Searchable, permanent visibility that compounds as the project grows. *** Sponsorship tiers Platinum $2,500 / month For companies that want maximum visibility and a direct stake in the project's direction. * Your brand, top-positioned across all docs pages * Your brand on GitHub README * Listed in every release changelog * Spotlight post on joining * Contextual mentions across relevant docs and content * Priority bug fixes and feature requests * Direct line to the maintainer [Become a Platinum sponsor ](https://github.com/sponsors/hey-api/sponsorships?tier_id=586996) Gold $1,000 / month For companies that depend on Hey API day-to-day and want to invest in its future. * Your brand across all docs pages * Your brand on GitHub README * Listed in every release changelog * Contextual mentions across relevant docs and content * Priority bug fixes and feature requests [Become a Gold sponsor ](https://github.com/sponsors/hey-api/sponsorships?tier_id=586998) Silver $500 / month * Your brand, prominently placed in docs and GitHub README * Contextual mentions across relevant docs and content [Become a Silver sponsor ](https://github.com/sponsors/hey-api/sponsorships?tier_id=586999) Bronze $250 / month * Your brand in docs and GitHub README * Contextual mentions across relevant docs and content [Become a Bronze sponsor ](https://github.com/sponsors/hey-api/sponsorships?tier_id=587000) Individual tiers also available at [$50 (Copper)](https://github.com/sponsors/hey-api/sponsorships?tier_id=587001) and [$10](https://github.com/sponsors/hey-api/sponsorships?tier_id=505129) per month. ### Need custom terms? Enterprise arrangements, invoice billing, and multi-year agreements available on request. [ Get in touch](mailto:lubos@heyapi.dev) *** Current sponsors Gold * [](https://kutt.to/pkEZyc) [Best-in-class interfaces for developers and agents.](https://kutt.to/pkEZyc) * [The open source AI coding agent.](https://kutt.to/QM9Q2N) Silver * [](https://kutt.to/skQUVd) * [](https://kutt.to/Dr9GuW) * [](https://kutt.to/yZVkdV) Bronze * [](https://kutt.to/YpaKsX) * [](https://kutt.to/HW4GYR) Friends * [](https://kutt.to/R6UuKW) * [](https://kutt.to/bcUF8q)