Skip to content

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.
  • httpClient and baseUrl.

Template first-class:

  • client
  • mode
  • mock
  • prettier
  • clean

Escape hatch:

  • project.templateOptions.path
  • project.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

FlagEffect
--http-client fetchOverrides project.config.httpClient regardless of config file.
--client swrEmits SWR-compatible client calls.
--mode split-tagSwitches Orval’s output mode.
--mock-type offDisables mock generation for the current run.
--mock-delay 1000Sets 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 generate regenerates source from the resolved contract inputs.
  • npm run build bundles the already generated source and does not rerun generation.
  • npm run publish runs build and then publishes without refetching contracts.

Current behaviour:

  • generate can trigger post-generation registry publish when project.publish enables it.
  • The generated package exposes a stable package entrypoint after build.
  • genxapi.manifest.json records 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.variables to inject your own placeholder values inside template files.
  • Use project.templateOptions.path to 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.path into 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.