Docs navigation
Orval API Client Template (@genxapi/template-orval)
The Orval template scaffolds a TypeScript package and delegates generator-specific behaviour to Orval. This guide covers installation, generated layout, and the correct package consumption boundary.
Capability Manifest
The Orval template now declares its capability surface explicitly.
Universal:
- Contract inputs and reproducibility metadata.
- Output layout.
httpClientandbaseUrl.
Template first-class:
clientmodemockprettierclean
Escape hatch:
project.templateOptions.pathproject.templateOptions.variables
The CLI no longer hardcodes Orval translation rules in shared core code. Instead, the Orval template owns unified-config transformation, template-only validation, and dependency planning.
Installation
npm install --save-dev @genxapi/cli @genxapi/template-orval
Orval itself remains a peer dependency – install whichever version you need:
npm install --save-dev orval
Generated project layout
Running npx genxapi generate with project.template: "orval" produces:
examples/<project>/
├── package.json # Includes build/test scripts, orval + rollup deps
├── orval.config.ts # Generated from unified config options
├── src/index.ts # Stable package entrypoint assembled by the template
├── src/
│ ├── <client>/client.ts # Fully-typed HTTP clients / hooks
│ └── <client>/model/… # Schemas & types
├── mocks/
│ └── handlers.ts # MSW handlers (when mocks enabled)
├── tsconfig.json # Project local TS settings
├── rollup.config.mjs # Builds `dist/`
└── README.md # Derived from config.project.readme
Configuration recap
All generator intent now lives under project.config and clients[].config:
{
"project": {
"template": "orval",
"output": "./src",
"config": {
"httpClient": "axios",
"client": "react-query",
"mode": "split",
"mock": { "type": "msw", "delay": 250 }
}
},
"clients": [
{
"name": "pets",
"swagger": "https://petstore3.swagger.io/api/v3/openapi.json",
"config": { "baseUrl": "https://api.pets.local" }
}
]
}
The CLI converts these options to Orval’s output block. For the exhaustive list of valid values, see the Orval documentation.
Consuming the generated SDK
Import the generated package boundary, not src/ or dist/ internals.
React Query hooks
With client: "react-query" you receive ready-made hooks:
import { pets } from "petstore-sdk";
export function PetsList() {
const { data, isLoading } = pets.useGetPetsQuery();
if (isLoading) return <p>Loading…</p>;
return (
<ul>
{data?.map((pet) => (
<li key={pet.id}>{pet.name}</li>
))}
</ul>
);
}
Switch project.config.client to "swr", "vue-query", "svelte-query", "axios", etc. to emit a different runtime.
Axios / Fetch clients
When client: "axios" (or "fetch") the template emits plain functions instead of hooks:
import { pets } from "petstore-sdk";
const result = await pets.getPets({ params: { limit: 10 } });
Use project.config.httpClient or the --http-client flag to toggle between axios and fetch under the hood.
Mock service worker (MSW)
Setting mock to an object enables MSW handler generation:
{
"project": {
"config": {
"mock": { "type": "msw", "useExamples": true }
}
}
}
Generated handlers live under mocks/handlers.ts and can be wired into your application or test suite:
import { setupServer } from "msw/node";
import { handlers } from "./mocks/handlers";
const server = setupServer(...handlers);
Disable mocks per client with clients[].config.mock = { "type": "off" } or globally with --mock-type off.
CLI overrides
| Flag | Effect |
|---|---|
--http-client fetch | Overrides project.config.httpClient regardless of config file. |
--client swr | Emits SWR-compatible client calls. |
--mode split-tag | Switches Orval’s output mode. |
--mock-type off | Disables mock generation for the current run. |
--mock-delay 1000 | Sets a 1s artificial delay in the generated MSW handlers. |
Rollup build & publishing
The template ships Rollup configuration that produces dist/index.js + dist/index.d.ts. The generated package now separates lifecycle scripts explicitly:
npm run generateregenerates source from the resolved contract inputs.npm run buildbundles the already generated source and does not rerun generation.npm run publishrunsbuildand then publishes without refetching contracts.
Current behaviour:
generatecan trigger post-generation registry publish whenproject.publishenables it.- The generated package exposes a stable package entrypoint after build.
genxapi.manifest.jsonrecords the resolved contract source, checksum, template, and output paths for traceability.- Package dependencies are derived from the selected Orval capabilities instead of copied as a fixed bundle.
- React Query, React, axios, MSW, Faker, and Zod dependencies are only added when the selected Orval feature surface requires them.
Planned later:
- Diff-driven release advice and SemVer intelligence belong to later phases, not this template.
Dependency Planning Notes
client: "fetch"with mocks disabled no longer pulls React Query, React, or MSW dependencies into the generated package.client: "react-query"adds the React Query runtime and peers because the generated package exports those hooks.httpClient: "axios"adds axios only when the generated package actually needs it.- The template surfaces documentation hints for richer Orval adapters that still need manual framework package pinning.
Customising further
- Use
project.templateOptions.variablesto inject your own placeholder values inside template files. - Use
project.templateOptions.pathto swap Orval scaffold files while keeping the Orval template contract. - If you need a different generator contract instead of an Orval scaffold tweak, create an explicit external template rather than stretching
project.templateOptions.pathinto a plugin system. - Combine with hooks to run tests, linting, or custom bundling steps. Hooks run after dependency installation but before publishing automation.
Resources
With the unified interface you can flip between React Query, SWR, axios, or fetch clients—and enable/disable mocks—without touching template internals. The CLI handles the heavy lifting so you can focus on consuming the generated SDK.