Orval OpenAPI TypeScript Client Generator
Orval is a robust TypeScript client generator for OpenAPI/Swagger specifications, designed to automate the creation of type-safe API clients. It supports generating clients with various data fetching libraries, including React Query, Svelte Query, Axios, and Fetch, and can also generate mock data using Faker.js. The current stable version is 8.8.0, with minor and patch releases occurring frequently to incorporate new features (like `useSetQueryData` helpers), address bugs, and maintain compatibility with evolving ecosystem standards. Orval distinguishes itself through extensive customization options via its configuration file, allowing developers to precisely tailor the generated output for specific frameworks and architectural patterns, and by deeply integrating with OpenAPI schema validation and TypeScript type checking workflows to ensure high-quality, maintainable code.
Common errors
-
Error: Cannot find module 'faker' or Cannot find package 'faker'
cause Attempting to generate mocks with Orval v8.5.0 or newer without explicitly installing Faker.js.fixInstall Faker.js: `npm install -D @faker-js/faker`. -
Error: ENOENT: no such file or directory, stat 'openapi.yaml'
cause The input OpenAPI specification file specified in `orval.config.ts` does not exist at the given path.fixVerify the `input` path in your Orval configuration, ensuring the file exists and the path is correct relative to where Orval is executed. -
Orval: Config file not found. Please create one, for example 'orval.config.ts'.
cause Orval command was executed without a recognized configuration file (e.g., `orval.config.ts`, `orval.config.js`) in the current or parent directories.fixCreate an `orval.config.ts` or `orval.config.js` file in your project root or specify its path using the `--config` flag. -
TypeError: (0 , import_core.defineConfig) is not a function
cause CommonJS (require) syntax is used to import `defineConfig` in an environment configured for ESM, or there's a misconfiguration with TypeScript's module resolution.fixEnsure your `orval.config.ts` uses ESM import syntax (`import { defineConfig } from 'orval';`) and your `tsconfig.json`'s `module` option is set appropriately (e.g., `"ESNext"` or `"NodeNext"`).
Warnings
- breaking Starting from Orval v8.5.0, Faker.js (or `@faker-js/faker`) is no longer an inlined dependency and becomes an optional peer dependency. If your configuration uses mock generation, you must explicitly install a compatible version of `faker` in your project.
- gotcha Orval lists `prettier` as a peer dependency. While not strictly required to run Orval, it is essential for formatting the generated code, especially if you use the `afterAllFilesWrite` hook for consistent code style.
- gotcha Orval has a minimum Node.js engine requirement of `>=18.17.0`. Running Orval in environments with older Node.js versions will result in execution failures.
- gotcha Frequent updates to Orval's internal schema parsing and code generation logic, as seen in various patch notes (e.g., 'broken model imports', 'correct schema import canonic'), can sometimes lead to unexpected changes or breakages in the generated client code's imports or type definitions across minor versions, requiring review after updates.
Install
-
npm install orval -
yarn add orval -
pnpm add orval
Imports
- defineConfig
const defineConfig = require('orval').defineConfig;import { defineConfig } from 'orval'; - OrvalConfig
import type { OrvalConfig } from 'orval'; - HooksOptions
import type { HooksOptions } from 'orval';
Quickstart
import { defineConfig } from 'orval';
export default defineConfig({
petstore: {
input: 'https://petstore.swagger.io/v2/swagger.json',
output: {
mode: 'split',
target: 'src/api/endpoints/petstore.ts',
schemas: 'src/api/model',
client: 'react-query', // or 'axios', 'fetch', 'svelte-query', 'vue-query'
mock: true,
clean: true,
override: {
mutator: {
path: './src/api/mutator/custom-instance.ts',
name: 'customInstance',
},
operations: {
listPets: {
mutation: true,
query: true,
},
},
},
},
hooks: {
afterAllFilesWrite: 'prettier --write',
},
},
});
// src/api/mutator/custom-instance.ts
import Axios, { AxiosRequestConfig } from 'axios';
export const AXIOS_INSTANCE = Axios.create({ baseURL: 'https://petstore.swagger.io/v2' });
export const customInstance = <T>(config: AxiosRequestConfig, options?: AxiosRequestConfig): Promise<T> => {
return AXIOS_INSTANCE({ ...config, ...options }).then((res) => res.data);
};
export default customInstance;
// package.json (scripts)
// {
// "scripts": {
// "generate-api": "orval"
// }
// }
//
// To run: `npm run generate-api` or `npx orval`