Skip to content

Unified Generator Config

Declare generator intent once and let the CLI translate it into the correct template-specific shape for the selected template.

📦 Schema reference – local file: packages/cli/schemas/genxapi.schema.json

Raw URL: https://raw.githubusercontent.com/genxapi/genxapi/main/packages/cli/schemas/genxapi.schema.json

Top-level structure

{
  "$schema": "https://raw.githubusercontent.com/genxapi/genxapi/main/packages/cli/schemas/genxapi.schema.json",
  "project": {
    "name": "multi-client-demo",
    "directory": "../examples/multi-client-demo",
    "template": "orval",
    "output": "./src",
    "config": {
      "httpClient": "axios",
      "client": "react-query"
    }
  },
  "clients": [
    {
      "name": "pets",
      "contract": {
        "source": "https://petstore3.swagger.io/api/v3/openapi.json",
        "snapshot": true
      },
      "config": {
        "baseUrl": "https://api.pets.local"
      }
    }
  ],
  "hooks": {
    "beforeGenerate": ["npm run lint"],
    "afterGenerate": ["npm test"]
  }
}
  • project.template accepts built-in aliases ("orval", "kubb"), fully-qualified package names, or an explicit external template reference object.
  • project.output defines the base directory for derived workspaces. Defaults to ./src/<client-name> if omitted.
  • project.config sets generator defaults; clients[].config provides per-client overrides.
  • clients[].swagger remains the shorthand contract field; clients[].contract is the first-class form for auth, snapshots, and checksums.
  • hooks remain unchanged from earlier releases.
  • Config format today can be JSON, YAML, or TypeScript.

Contract sources

Every client can declare its contract in one of two ways:

  • swagger: "https://..." or swagger: "./specs/pets.yaml" for the compact form.
  • contract: { ... } for reproducible workflows, authenticated remote fetches, and manifest metadata.
FieldTypeBehaviour
contract.sourcestringLocal path or remote URL for the OpenAPI/Swagger document.
contract.auth{ type: "bearer", tokenEnv } or { type: "basic", usernameEnv, passwordEnv } or { type: "header", headerName, valueEnv, prefix? }Uses environment variables at generation time so secrets stay out of config files and logs.
contract.snapshotboolean or { path?: string }Writes a local snapshot that the generator consumes. This is the recommended mode for remote inputs and is required for authenticated remote contracts.
contract.checksumboolean or { algorithm?: "sha256" | "sha512" }Calculates a checksum and records it in genxapi.manifest.json.

Notes:

  • Remote contracts are safer and more reproducible when snapshot is enabled because the generator reads a fixed file instead of refetching a mutable URL.
  • Authenticated remote contracts are always resolved before template execution so Orval/Kubb never need direct secret access in their config files.
  • genxapi.manifest.json captures the resolved contract source, snapshot path, checksum, output paths, template, and generation timestamp for traceability.

Secure remote contract example

{
  "clients": [
    {
      "name": "pets",
      "contract": {
        "source": "https://api.example.com/openapi.json",
        "auth": {
          "type": "bearer",
          "tokenEnv": "OPENAPI_TOKEN"
        },
        "snapshot": {
          "path": ".genxapi/contracts/pets.json"
        },
        "checksum": {
          "algorithm": "sha256"
        }
      }
    }
  ]
}

OPENAPI_TOKEN should be injected by your shell, CI system, or secret manager. Do not hardcode tokens in source URLs or config files.

GeneratorOptions

GenX API now treats these settings as three distinct ownership classes:

  • Universal options are shared intent that the core understands and templates map into their own native config.
  • Template first-class options are documented, supported parts of a specific template surface.
  • Escape hatch options stay template-owned and are passed through or handled by the template without being promoted as universal API.
FieldTypeApplies toBehaviour
httpClient"axios" | "fetch"Orval & KubbSets the HTTP transport (Orval output.httpClient, Kubb plugin-client.client).
client"react-query", "swr", "vue-query", "svelte-query", "axios", "axios-functions", "angular", "zod", "fetch"OrvalSelects the runtime client flavour.
mode"single", "split", "split-tag", "split-tags", "tags", "tags-split"OrvalMaps to Orval’s output mode.
baseUrlstringOrval & KubbInjects a default base URL (output.baseUrl, plugin-client.baseURL).
mockboolean or { type: "msw" | "off", delay?: number, useExamples?: boolean }OrvalControls MSW mock generation. type: "off" disables mocks.
prettierbooleanOrvalToggles Prettier formatting in generated files.
cleanbooleanOrvalToggles cleanup of Orval output before writing new files.
plugins / kubb{ client?: object, ts?: object, oas?: object }KubbMerged into the corresponding Kubb plugin blocks.

All properties are optional. Merge order is project.config → clients[].config → CLI overrides.

Capability Ownership By Template

Universal

  • Contract source selection, auth, snapshot, and checksum.
  • Output layout (project.output, clients[].output).
  • httpClient and baseUrl.

Orval first-class

  • client
  • mode
  • mock
  • prettier
  • clean

Kubb first-class

  • plugins.client
  • plugins.ts
  • plugins.oas
  • kubb.client
  • kubb.ts
  • kubb.oas

Escape hatches

  • project.templateOptions.path
  • project.templateOptions.variables
  • Raw Kubb plugin pass-through inside plugins / kubb

Template-specific validation now lives inside the template boundary. For example, the Orval template rejects Kubb-only plugin blocks, and the Kubb template rejects Orval-only mode / mock style settings.

Template Selection

Built-in template

{
  "project": {
    "template": "orval"
  }
}

Explicit external template

{
  "project": {
    "template": {
      "provider": "external",
      "module": "@acme/genxapi-template",
      "export": "genxTemplate"
    }
  }
}

module can be a package name or a relative/absolute filesystem path. Relative paths resolve from the config file directory.

Use the explicit external form when you want a real external template contract with capability manifests, validation hooks, config transformation, generation hooks, dependency planning, and plan/report participation.

Use project.templateOptions.path only to swap scaffold files inside an already selected template.

CLI flag parity

FlagConfig fieldNotes
--templateproject.templateSame alias resolution as the config file.
--http-clientconfig.httpClientApplies to every client post-parse.
--clientconfig.clientOnly used by Orval.
--modeconfig.modeOrval output mode override.
--base-urlconfig.baseUrlOverwrites both Orval and Kubb defaults.
--mock-typeconfig.mock.typeUse msw or off.
--mock-delayconfig.mock.delayInteger milliseconds.
--mock-use-examplesconfig.mock.useExamples = trueFlag (omit to leave unchanged).

The CLI merges overrides after validation, ensuring they win over file-based values.

Note: --template accepts alias and package strings. Use the config file when you need an explicit external template object with provider, module, or a non-default export name.

Mapping to templates

Orval (@genxapi/template-orval)

Unified optionOrval outputNotes
httpClientoutput.httpClientOnly emitted when provided.
clientoutput.clientValues align with Orval’s client catalogue.
modeoutput.modeSupports split, split-tags, etc.
baseUrloutput.baseUrlLeave undefined to keep Orval’s default.
mockoutput.mockBoolean or MSW object. { type: "off" } becomes false.
prettieroutput.prettierMirrors Orval toggle.
cleanoutput.cleanMirrors Orval toggle.

ℹ️ Dive into the Orval documentation for the exhaustive list of supported Orval options.

Kubb (@genxapi/template-kubb)

Unified optionKubb pluginNotes
httpClientplugin-client.clientAccepts fetch or axios.
baseUrlplugin-client.baseURLOptional base URL.
plugins.clientplugin-clientMerge additional fields (dataReturnType, operations, etc.).
plugins.tsplugin-tsControls enum style, barrel strategy, syntax.
plugins.oasplugin-oasControls validation, output path, discriminator handling.

Any extra keys under plugins.* are copied verbatim to kubb.config.ts.

Sample configurations

Orval-flavoured project

{
  "project": {
    "template": "orval",
    "output": "./src",
    "config": {
      "httpClient": "axios",
      "client": "react-query",
      "mock": { "type": "msw", "useExamples": true }
    }
  },
  "clients": [
    {
      "name": "pets",
      "swagger": "https://petstore3.swagger.io/api/v3/openapi.json",
      "config": { "baseUrl": "https://api.pets.local" }
    },
    {
      "name": "store",
      "swagger": "https://petstore3.swagger.io/api/v3/openapi.json",
      "config": {
        "client": "axios",
        "mock": { "type": "off" }
      }
    }
  ]
}

Kubb-flavoured project

{
  "project": {
    "template": "kubb",
    "output": "./src",
    "config": {
      "httpClient": "fetch",
      "plugins": {
        "client": { "dataReturnType": "data" },
        "ts": { "enumType": "asConst" }
      }
    }
  },
  "clients": [
    {
      "name": "pets",
      "swagger": "https://petstore3.swagger.io/api/v3/openapi.json"
    },
    {
      "name": "store",
      "swagger": "https://petstore3.swagger.io/api/v3/openapi.json",
      "config": {
        "httpClient": "axios",
        "plugins": {
          "client": { "dataReturnType": "full" },
          "ts": { "enumType": "enum" }
        }
      }
    }
  ]
}

Migration tips

  • Set project.template to "orval" or "kubb" (or an explicit external template reference if you own a custom template contract).
  • Move shared fields from clients[].orval / clients[].kubb into project.config.
  • Replace template-specific blocks with clients[].config overrides.
  • (Optional) Introduce project.output so path defaults are derived automatically.
  • Delete redundant per-client output.workspace / output.target entries if the defaults suit your layout.

The CLI still understands the legacy structure, but new capabilities (HTTP client overrides, advanced mock settings, plugin merges) are only available through the unified schema.

When to Favour CLI Overrides

  • CI smoke tests – npx genxapi generate --dry-run --mock-type off lets you disable mocks without editing shared config.
  • Ad-hoc builds – experiments with --client zod or --http-client fetch remain local.
  • Template switching – --template kubb instantly switches engines, keeping the same clients[].config contract.

With this unified interface you can add engines, rotate defaults, or run per-environment overrides without rewriting configuration files.

For the manifest structure emitted by generation, see Generation manifest. For external template authoring guidance, see External template authoring.