Programmatic API
Use Orval programmatically in your build scripts
Integrate Orval code generation into your build processes, scripts, or tools.
Basic Usage
import orval from 'orval';
// Generate using a config file path
await orval('./orval.config.js');
// Generate using current directory's orval config
await orval();Or use the named export:
import { generate } from 'orval';
await generate('./orval.config.js');Direct Configuration
Pass a configuration object directly:
import { generate, type Options } from 'orval';
const config: Options = {
input: {
target: './api-spec.yaml',
},
output: {
target: './src/api.ts',
client: 'axios',
},
};
await generate(config);Global Options Override
Override config settings with global options. See the GlobalOptions interface for all available options.
import { generate, type GlobalOptions } from 'orval';
const globalOptions: GlobalOptions = {
// File watching
watch: true, // Enable watch mode (boolean)
// watch: './specs/**/*.yaml', // Watch specific file pattern (string)
// watch: ['./specs/*.yaml'], // Watch multiple patterns (string[])
// Output control
clean: true, // Clean all output directories (boolean)
// clean: ['./src/api', './types'], // Clean specific directories (string[])
output: './src/generated', // Override output directory
// Code formatting (only one formatter can be used at a time)
formatter: 'prettier', // 'prettier' | 'biome' | 'oxfmt'
// HTTP client configuration
client: 'fetch', // Override HTTP client
httpClient: 'fetch', // HTTP implementation: 'axios' | 'fetch'
// Generation mode
mode: 'split', // Output mode: 'single' | 'split' | 'tags' | 'tags-split'
// Mock data generation
mock: true, // Enable mock data generation
// mock: { generators: [{ type: 'msw', delay: 1000 }] }, // Configure mock options
// TypeScript configuration
tsconfig: './tsconfig.json', // Custom tsconfig path
// tsconfig: { compilerOptions: {...} }, // Inline tsconfig
// Package configuration
packageJson: './package.json',
input: './api-spec.yaml',
// Logging
logLevel: 'error', // Only log errors
// Error handling
throwOnError: true, // Throw initial generation errors instead of only logging them
};
await generate('./orval.config.js', process.cwd(), globalOptions);Custom Workspace
Specify a custom workspace directory:
import { generate } from 'orval';
const workspace = '/path/to/your/project';
await generate('./orval.config.js', workspace);Function Signature
function generate(
optionsExport?: string | OptionsExport,
workspace?: string,
options?: GlobalOptions,
): Promise<void>;Parameters:
optionsExport: Path to config file or configuration objectworkspace: Working directory (defaults toprocess.cwd())options: Global options to override config settings
Error Handling
By default, generate() logs initial generation errors and resolves after processing the configured project or projects. Set throwOnError when a script needs to catch initial generation failures and decide how to handle them:
import { generate } from 'orval';
try {
await generate('./orval.config.js', process.cwd(), {
throwOnError: true,
});
} catch {
process.exit(1);
}generate() logs the error through the active reporter before rethrowing. logger.error is a no-op outside withReporter, so do not use it in this catch block.
When a config file contains multiple projects, throwOnError stops on the first generation error during the initial run instead of continuing with later projects. Watch mode generation errors are still logged after the watcher has started.
Reporter
Reporter selection is a programmatic execution concern, not an orval.config.ts option. Built-in packages emit structured events (message, packageName, and optional projectName) to the reporter that is active for the current async call chain.
| Entry point | Default |
|---|---|
Lower-level APIs (generateSpec, helpers, formatters) | No-op |
CLI (orval) | Console |
Public generate() | Console, unless an outer withReporter is already active |
Use withReporter to install a reporter for one call chain. An outer reporter always wins over generate()'s console default, so tests can silence output without changing production callers.
import { generate, withReporter, noopReporter, consoleReporter } from 'orval';
// Quiet a programmatic generate() in tests
await withReporter(noopReporter, () => generate(config));
// Opt lower-level APIs into the existing terminal output
await withReporter(consoleReporter, () => generateSpec(workspace, options));Custom reporters receive the structured event. When a project is in scope, the logger prefixes message with that project name. Messages keep their current wording and ANSI styling; strip colors if you need plain text.
import { generate, withReporter, type OrvalReporter } from 'orval';
const reporter: OrvalReporter = {
info: (event) => process.stdout.write(`${event.packageName}: ${event.message}\n`),
warn: (event) => process.stderr.write(`${event.packageName}: ${event.message}\n`),
error: (event) => process.stderr.write(`${event.packageName}: ${event.message}\n`),
verbose: (event) => process.stderr.write(`${event.packageName}: ${event.message}\n`),
debug: (event) => {
if (process.env.DEBUG) {
process.stderr.write(`${event.packageName}: ${event.message}\n`);
}
},
};
await withReporter(reporter, () => generate(config));To assert one or more events in a test, override only the levels you care about:
import { generate, noopReporter, withReporter } from 'orval';
import { vi } from 'vitest';
const warn = vi.fn();
await withReporter({ ...noopReporter, warn }, () => generate(config));
expect(warn).toHaveBeenCalledWith(
expect.objectContaining({
packageName: 'orval',
message: expect.stringContaining('symbolic link'),
}),
);Watch Mode
import { generate } from 'orval';
// Enable watch mode
await generate('./orval.config.js', process.cwd(), {
watch: true,
});
// Watch specific files/directories
await generate('./orval.config.js', process.cwd(), {
watch: ['./specs/*.yaml', './src/custom-types.ts'],
});Build Scripts Integration
{
"scripts": {
"generate": "node scripts/generate-api.js",
"dev": "npm run generate && next dev",
"build": "npm run generate && next build"
}
}const { generate } = require('orval');
async function main() {
try {
await generate();
console.log('API client generated successfully');
} catch (error) {
console.error('Failed to generate API client:', error);
process.exit(1);
}
}
main();