Orval - OpenAPI to TypeScript Code Generator
Orval generates type-safe TypeScript clients, hooks, schemas, mocks, and server handlers from OpenAPI v3/Swagger v2 specifications.
Quick Start
Installation
npm install orval -D
# or yarn add orval -D
# or pnpm add orval -D
# or bun add orval -D
Minimal Configuration
import { defineConfig } from 'orval';
export default defineConfig({
petstore: {
input: {
target: './petstore.yaml',
},
output: {
target: './src/api/petstore.ts',
schemas: './src/api/model',
client: 'react-query',
},
},
});
Run
npx orval
npx orval --config ./orval.config.ts
npx orval --project petstore
npx orval --watch
Choosing Your Setup
Client Selection Guide
| Use Case |
Client |
httpClient |
Notes |
| React with server state |
react-query |
fetch or axios |
TanStack Query hooks |
| Vue 3 with server state |
vue-query |
fetch or axios |
TanStack Query for Vue |
| Svelte with server state |
svelte-query |
fetch or axios |
TanStack Query for Svelte |
| SolidJS standalone app |
solid-query |
fetch or axios |
TanStack Query for Solid |
| SolidStart full-stack |
solid-start |
native fetch |
Uses query()/action() primitives |
| Angular with signals |
angular-query |
angular |
Injectable functions, signal reactivity |
| Angular traditional |
angular |
— |
HttpClient services |
| React with SWR |
swr |
fetch or axios |
Vercel SWR hooks |
| Lightweight / Edge |
fetch |
— |
Zero dependencies, works everywhere |
| Node.js / existing Axios |
axios-functions |
— |
Factory functions (default) |
| Axios with DI |
axios |
— |
Injectable Axios instance |
| Validation only |
zod |
— |
Zod schemas, no HTTP client |
| Backend API server |
hono |
— |
Hono handlers with Zod validation |
| AI agent tools |
mcp |
— |
Model Context Protocol servers |
Mode Selection Guide
single — Everything in one file. Best for small APIs.
split — Separate files: petstore.ts, petstore.schemas.ts, petstore.msw.ts. Good for medium APIs.
tags — One file per OpenAPI tag + shared schemas. Organizes by domain.
tags-split — Folder per tag with split files. Best for large APIs. Recommended.
httpClient Option
For react-query, vue-query, svelte-query, and swr clients:
output: {
client: 'react-query',
httpClient: 'fetch', // 'fetch' (default) | 'axios'
}
For angular-query:
output: {
client: 'angular-query',
httpClient: 'angular', // Uses Angular HttpClient
}
Configuration Reference
Config Structure
import { defineConfig } from 'orval';
export default defineConfig({
[projectName]: {
input: InputOptions,
output: OutputOptions,
hooks: HooksOptions,
},
});
Multiple projects can share the same config file with different input/output settings.
Input Options
input: {
target: './spec.yaml', // Path or URL to OpenAPI spec (required)
override: {
transformer: './transform.js', // Transform spec before generation
},
filters: {
mode: 'include', // 'include' | 'exclude'
tags: ['pets', /health/], // Filter by OpenAPI tags
schemas: ['Pet', /Error/], // Filter by schema names
},
parserOptions: {
headers: [ // Auth headers for remote spec URLs
{
domains: ['api.example.com'],
headers: {
Authorization: 'Bearer YOUR_TOKEN',
'X-API-Key': 'your-api-key',
},
},
],
},
}
Output Options
output: {
target: './src/api/endpoints.ts', // Output path (required)
client: 'react-query', // Client type (see table above)
httpClient: 'fetch', // 'fetch' (default) | 'axios' | 'angular'
mode: 'tags-split', // 'single' | 'split' | 'tags' | 'tags-split'
schemas: './src/api/model', // Output path for model types
operationSchemas: './src/api/params', // Separate path for operation-derived types
workspace: 'src/', // Base folder for all files
fileExtension: '.ts', // Custom file extension
namingConvention: 'camelCase', // File naming: camelCase | PascalCase | snake_case | kebab-case
indexFiles: true, // Generate index.ts barrel files
clean: true, // Clean output before generating
prettier: true, // Format with Prettier
biome: true, // Format with Biome
headers: true, // Generate header parameters
baseUrl: '/api/v2', // API base URL
// or from spec:
// baseUrl: { getBaseUrlFromSpecification: true, index: 0, variables: { environment: 'api.dev' } },
mocks: true, // Generate MSW + Faker mocks (boolean, object, or function)
docs: true, // Generate TypeDoc documentation
// docs: { configPath: './typedoc.config.mjs' },
allParamsOptional: true, // Make all params optional (except path params)
urlEncodeParameters: true, // URL-encode path/query parameters
optionsParamRequired: false, // Make options parameter required
propertySortOrder: 'Specification', // 'Alphabetical' | 'Specification'
tsconfig: './tsconfig.json', // Custom tsconfig path
override: { ... }, // Advanced overrides (see below)
}
Multiple API Specs
export default defineConfig({
petstoreV1: {
input: { target: './specs/v1.yaml' },
output: { target: 'src/api/v1', client: 'react-query' },
},
petstoreV2: {
input: { target: './specs/v2.yaml' },
output: { target: 'src/api/v2', client: 'react-query' },
},
});
Filter Endpoints
input: {
target: './spec.yaml',
filters: {
mode: 'include',
tags: ['pets'],
},
}
Detailed Guides
When the user's question involves a specific topic below, read the corresponding file from this skill's directory.
| Topic |
File |
Load when user asks about... |
| TanStack Query / SWR |
tanstack-query.md |
React Query, Vue Query, Svelte Query, Solid Query, SWR, query hooks, invalidation, infinite queries, suspense, prefetch |
| Angular |
angular.md |
Angular Query, Angular HttpClient, signals, inject functions, Angular services, providedIn |
| SolidStart |
solid-start.md |
SolidStart, @solidjs/router, query(), action(), createAsync, revalidate |
| Custom HTTP / Auth |
custom-http-clients.md |
Custom mutator, authentication, tokens, interceptors, custom fetch/axios, baseURL, hook-based mutator |
| Zod Validation |
zod-validation.md |
Zod schemas, validation, runtime validation, coerce, strict, preprocess |
| Mocking / MSW |
mocking-msw.md |
MSW mocks, testing, test setup, faker, Vitest, mock handlers, useExamples |
| Hono Server |
hono.md |
Hono handlers, zValidator, composite routes, context types, server-side generation |
| Advanced Config |
advanced-config.md |
Type generation, enums, per-operation overrides, FormData, JSDoc, params serializer, full example |
| Tooling / Workflow |
tooling-workflow.md |
Programmatic API, transformers, hooks, NDJSON streaming, MCP, afterAllFilesWrite |
OpenAPI Specification Best Practices
- Use unique
operationId for every operation — Orval uses these for function and hook names
- Define reusable schemas in
components/schemas — reduces duplication in generated types
- Use tags to group operations — works with
tags and tags-split modes
- Define response types for all operations — enables full type safety
- Mark required fields — affects optional/required in generated TypeScript interfaces
- Use
x-enumNames for numeric enums — generates readable const names
- Provide
example values — used by mock generation when useExamples: true
- Use
application/x-ndjson content type for streaming endpoints — enables typed NDJSON generation
CLI Reference
orval # Generate using auto-discovered config
orval --config ./api/orval.config.ts # Specify config file
orval --project petstore # Run specific project(s)
orval --watch # Watch mode
orval --watch ./src # Watch specific directory
orval --clean # Clean generated files
orval --prettier # Format with Prettier
orval --biome # Format with Biome
orval --tsconfig ./src/tsconfig.json # Custom tsconfig path
orval --mode split # Override output mode
orval --client react-query # Override client
orval --mock # Override mock generation
orval --input ./spec.yaml --output ./api.ts # Direct generation
Resources
1---2name: orval3description: Generate type-safe API clients, TanStack Query/SWR hooks, Zod schemas, MSW mocks, Hono server handlers, MCP servers, and SolidStart actions from OpenAPI specs using Orval. Covers all clients (React/Vue/Svelte/Solid/Angular Query, Fetch, Axios), custom HTTP mutators, authentication patterns, NDJSON streaming, programmatic API, and advanced configuration.4---5
6# Orval - OpenAPI to TypeScript Code Generator
7
8Orval generates type-safe TypeScript clients, hooks, schemas, mocks, and server handlers from OpenAPI v3/Swagger v2 specifications.
9
10## Quick Start
11
12### Installation
13
14```bash
15npm install orval -D
16# or yarn add orval -D
17# or pnpm add orval -D
18# or bun add orval -D
19```
20
21### Minimal Configuration
22
23```ts
24import { defineConfig } from 'orval';
25
26export default defineConfig({
27 petstore: {
28 input: {
29 target: './petstore.yaml',
30 },
31 output: {
32 target: './src/api/petstore.ts',
33 schemas: './src/api/model',
34 client: 'react-query',
35 },
36 },
37});
38```
39
40### Run
41
42```bash
43npx orval
44npx orval --config ./orval.config.ts
45npx orval --project petstore
46npx orval --watch
47```
48
49## Choosing Your Setup
50
51### Client Selection Guide
52
53| Use Case | Client | httpClient | Notes |
54| ------------------------ | ----------------- | ------------------ | --------------------------------------- |
55| React with server state | `react-query` | `fetch` or `axios` | TanStack Query hooks |
56| Vue 3 with server state | `vue-query` | `fetch` or `axios` | TanStack Query for Vue |
57| Svelte with server state | `svelte-query` | `fetch` or `axios` | TanStack Query for Svelte |
58| SolidJS standalone app | `solid-query` | `fetch` or `axios` | TanStack Query for Solid |
59| SolidStart full-stack | `solid-start` | native fetch | Uses `query()`/`action()` primitives |
60| Angular with signals | `angular-query` | `angular` | Injectable functions, signal reactivity |
61| Angular traditional | `angular` | — | HttpClient services |
62| React with SWR | `swr` | `fetch` or `axios` | Vercel SWR hooks |
63| Lightweight / Edge | `fetch` | — | Zero dependencies, works everywhere |
64| Node.js / existing Axios | `axios-functions` | — | Factory functions (default) |
65| Axios with DI | `axios` | — | Injectable Axios instance |
66| Validation only | `zod` | — | Zod schemas, no HTTP client |
67| Backend API server | `hono` | — | Hono handlers with Zod validation |
68| AI agent tools | `mcp` | — | Model Context Protocol servers |
69
70### Mode Selection Guide
71
72- **`single`** — Everything in one file. Best for small APIs.
73- **`split`** — Separate files: `petstore.ts`, `petstore.schemas.ts`, `petstore.msw.ts`. Good for medium APIs.
74- **`tags`** — One file per OpenAPI tag + shared schemas. Organizes by domain.
75- **`tags-split`** — Folder per tag with split files. Best for large APIs. Recommended.
76
77### httpClient Option
78
79For `react-query`, `vue-query`, `svelte-query`, and `swr` clients:
80
81```ts
82output: {
83 client: 'react-query',
84 httpClient: 'fetch', // 'fetch' (default) | 'axios'
85}
86```
87
88For `angular-query`:
89
90```ts
91output: {
92 client: 'angular-query',
93 httpClient: 'angular', // Uses Angular HttpClient
94}
95```
96
97## Configuration Reference
98
99### Config Structure
100
101```ts
102import { defineConfig } from 'orval';
103
104export default defineConfig({
105 [projectName]: {
106 input: InputOptions,
107 output: OutputOptions,
108 hooks: HooksOptions,
109 },
110});
111```
112
113Multiple projects can share the same config file with different input/output settings.
114
115### Input Options
116
117```ts
118input: {
119 target: './spec.yaml', // Path or URL to OpenAPI spec (required)
120 override: {
121 transformer: './transform.js', // Transform spec before generation
122 },
123 filters: {
124 mode: 'include', // 'include' | 'exclude'
125 tags: ['pets', /health/], // Filter by OpenAPI tags
126 schemas: ['Pet', /Error/], // Filter by schema names
127 },
128 parserOptions: {
129 headers: [ // Auth headers for remote spec URLs
130 {
131 domains: ['api.example.com'],
132 headers: {
133 Authorization: 'Bearer YOUR_TOKEN',
134 'X-API-Key': 'your-api-key',
135 },
136 },
137 ],
138 },
139}
140```
141
142### Output Options
143
144```ts
145output: {
146 target: './src/api/endpoints.ts', // Output path (required)
147 client: 'react-query', // Client type (see table above)
148 httpClient: 'fetch', // 'fetch' (default) | 'axios' | 'angular'
149 mode: 'tags-split', // 'single' | 'split' | 'tags' | 'tags-split'
150 schemas: './src/api/model', // Output path for model types
151 operationSchemas: './src/api/params', // Separate path for operation-derived types
152 workspace: 'src/', // Base folder for all files
153 fileExtension: '.ts', // Custom file extension
154 namingConvention: 'camelCase', // File naming: camelCase | PascalCase | snake_case | kebab-case
155 indexFiles: true, // Generate index.ts barrel files
156 clean: true, // Clean output before generating
157 prettier: true, // Format with Prettier
158 biome: true, // Format with Biome
159 headers: true, // Generate header parameters
160 baseUrl: '/api/v2', // API base URL
161 // or from spec:
162 // baseUrl: { getBaseUrlFromSpecification: true, index: 0, variables: { environment: 'api.dev' } },
163 mocks: true, // Generate MSW + Faker mocks (boolean, object, or function)
164 docs: true, // Generate TypeDoc documentation
165 // docs: { configPath: './typedoc.config.mjs' },
166 allParamsOptional: true, // Make all params optional (except path params)
167 urlEncodeParameters: true, // URL-encode path/query parameters
168 optionsParamRequired: false, // Make options parameter required
169 propertySortOrder: 'Specification', // 'Alphabetical' | 'Specification'
170 tsconfig: './tsconfig.json', // Custom tsconfig path
171 override: { ... }, // Advanced overrides (see below)
172}
173```
174
175### Multiple API Specs
176
177```ts
178export default defineConfig({
179 petstoreV1: {
180 input: { target: './specs/v1.yaml' },
181 output: { target: 'src/api/v1', client: 'react-query' },
182 },
183 petstoreV2: {
184 input: { target: './specs/v2.yaml' },
185 output: { target: 'src/api/v2', client: 'react-query' },
186 },
187});
188```
189
190### Filter Endpoints
191
192```ts
193input: {
194 target: './spec.yaml',
195 filters: {
196 mode: 'include',
197 tags: ['pets'],
198 },
199}
200```
201
202## Detailed Guides
203
204When the user's question involves a specific topic below, read the corresponding file from this skill's directory.
205
206| Topic | File | Load when user asks about... |
207| -------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
208| TanStack Query / SWR | [tanstack-query.md](tanstack-query.md) | React Query, Vue Query, Svelte Query, Solid Query, SWR, query hooks, invalidation, infinite queries, suspense, prefetch |
209| Angular | [angular.md](angular.md) | Angular Query, Angular HttpClient, signals, inject functions, Angular services, providedIn |
210| SolidStart | [solid-start.md](solid-start.md) | SolidStart, @solidjs/router, query(), action(), createAsync, revalidate |
211| Custom HTTP / Auth | [custom-http-clients.md](custom-http-clients.md) | Custom mutator, authentication, tokens, interceptors, custom fetch/axios, baseURL, hook-based mutator |
212| Zod Validation | [zod-validation.md](zod-validation.md) | Zod schemas, validation, runtime validation, coerce, strict, preprocess |
213| Mocking / MSW | [mocking-msw.md](mocking-msw.md) | MSW mocks, testing, test setup, faker, Vitest, mock handlers, useExamples |
214| Hono Server | [hono.md](hono.md) | Hono handlers, zValidator, composite routes, context types, server-side generation |
215| Advanced Config | [advanced-config.md](advanced-config.md) | Type generation, enums, per-operation overrides, FormData, JSDoc, params serializer, full example |
216| Tooling / Workflow | [tooling-workflow.md](tooling-workflow.md) | Programmatic API, transformers, hooks, NDJSON streaming, MCP, afterAllFilesWrite |
217
218## OpenAPI Specification Best Practices
219
2201. **Use unique `operationId`** for every operation — Orval uses these for function and hook names
2212. **Define reusable schemas** in `components/schemas` — reduces duplication in generated types
2223. **Use tags** to group operations — works with `tags` and `tags-split` modes
2234. **Define response types** for all operations — enables full type safety
2245. **Mark required fields** — affects optional/required in generated TypeScript interfaces
2256. **Use `x-enumNames`** for numeric enums — generates readable const names
2267. **Provide `example` values** — used by mock generation when `useExamples: true`
2278. **Use `application/x-ndjson`** content type for streaming endpoints — enables typed NDJSON generation
228
229## CLI Reference
230
231```bash
232orval # Generate using auto-discovered config
233orval --config ./api/orval.config.ts # Specify config file
234orval --project petstore # Run specific project(s)
235orval --watch # Watch mode
236orval --watch ./src # Watch specific directory
237orval --clean # Clean generated files
238orval --prettier # Format with Prettier
239orval --biome # Format with Biome
240orval --tsconfig ./src/tsconfig.json # Custom tsconfig path
241orval --mode split # Override output mode
242orval --client react-query # Override client
243orval --mock # Override mock generation
244orval --input ./spec.yaml --output ./api.ts # Direct generation
245```
246
247## Resources
248
249- [Documentation](https://orval.dev)
250- [GitHub](https://github.com/orval-labs/orval)
251- [Sample Projects](https://github.com/orval-labs/orval/tree/master/samples)