Skip to content

Options

Pass these options to pluginFetch() to control what it generates and where the files go.

Option Type Default Description
output Output { path: 'clients', barrel: { type: 'named' } } Where the generated files are written and exported
group Group Split output into per-tag or per-path folders
baseURL string Base URL prepended to every request
validator false | 'zod' | { request?: 'zod'; response?: 'zod' } false Validate request and response bodies with Zod
sdk { mode?: 'tag' | 'flat'; name?: string } Generate a class-based SDK instead of functions
include Array<Include> Keep only operations that match
exclude Array<Exclude> [] Skip operations that match
override Array<Override> [] Apply different options per pattern
resolver ResolverPatch<ResolverClient> Customize generated names and file paths
macros Array<Macro> Rewrite AST nodes before printing

output

Where the plugin writes its generated .ts files and how it exports them.

output.path

Folder for the plugin's files, resolved against the global output.path on defineConfig and defaulting to 'clients'. To write everything to one file, set output.mode: 'file' and give path a file name with its extension, such as 'clients.ts'.

output.mode

How the plugin consolidates its code into files, either 'file' or 'directory', defaulting to 'file'.

  • 'file' writes everything into a single file, so output.path must include the extension (see above).
  • 'directory' writes one file per operation under output.path.

IMPORTANT

group requires mode: 'directory'. Pairing group with mode: 'file' (or leaving mode unset) stops the build with a KUBB_INVALID_PLUGIN_OPTIONS error.

output.barrel

Toggle the export style and depth to see the generated barrels.

  • src/gen/
  • models/
  • Pet.ts
  • User.ts
  • clients/
  • pet/
  • getPetById.ts
  • store/
  • getInventory.ts
src/gen/index.ts

Controls how the generated index.ts (barrel) re-exports the output. Accepts { type: 'named' } or { type: 'all' }, optionally with nested: true (for example { type: 'named', nested: true }) to write an index.ts in every subdirectory, or false to skip the barrel entirely. Each generator plugin defaults output.barrel to { type: 'named' }; the root output.barrel on defineConfig defaults to false.

output.banner

Text added to the top of every generated file, such as a license header or @ts-nocheck directive. Pass a string, or a function (meta: BannerMeta) => string that receives the document info (title, description, version, baseURL) and per-file context (filePath, baseName, isBarrel, isAggregation), so a directive can skip barrel files.

Text added to the bottom of every generated file (string or (meta: BannerMeta) => string), like banner but for closing comments. Pair banner: '/* eslint-disable */' with footer: '/* eslint-enable */' to scope a lint disable to the generated file.

group

Switch the mode to see where these operations land on disk.

clients/pet/
  • getPetById
  • addPet
clients/store/
  • getInventory
clients/order/
  • placeOrder
  • getOrderById
clients/user/
  • loginUser
group: { type: "tag" } splits the output by the operation tag, so placeOrder follows its order tag.

Splits generated files into subfolders by the operation's tag or URL path, each under {output.path}/{groupName}/. Without group, every file lands directly in output.path. It applies only to output.mode: 'directory'.

IMPORTANT

Combining group with output.mode: 'file' stops the build with a KUBB_INVALID_PLUGIN_OPTIONS error.

group.type

Property used to assign each operation to a group ('tag' | 'path'), required whenever group is set. An operation with no tag goes in the default group.

  • 'tag' uses the operation's first tag.
  • 'path' uses the first URL segment, such as pet for /pet/{petId}.

group.name

Function (context: { group: string }) => string that turns a group key into a folder name. It defaults to the camelCased tag for a 'tag' group or the first path segment for a 'path' group, and a group.name you pass always wins.

baseURL

Base URL prepended to every request. When omitted, no host is prepended and each request uses the operation's relative path from the spec. A value containing a ${...} interpolation is emitted as a template literal in the generated client config, so baseURL: '${process.env.API_URL}' reads the environment variable at runtime.

validator

Runtime validator applied to request and response bodies using schemas from @kubb/plugin-zod, defaulting to false.

  • false does no validation and returns the response cast to the generated type.
  • 'zod' validates the success response body, and the error body when a non-2xx call does not throw.
  • { request?: 'zod', response?: 'zod' } opts in per direction, validating the request body before the call and the response body after.

Add @kubb/plugin-zod to the plugins list when either direction is 'zod'. With validation on the generated function throws a ParseError when a body fails its schema.

sdk

Generates a class-based SDK instead of standalone functions, accepting { mode?: 'tag' | 'flat'; name?: string }. Each tag client is an instance class whose constructor takes a client config and builds its own client, so every environment is a separate instance. Leave sdk unset to keep the per-operation functions that the query plugins consume.

mode: 'tag' (the default) emits one class per tag, such as PetClient and StoreClient. Set sdk.name alongside it to also emit a composed root class that instantiates every tag client from one shared config, reached as new PetStore(config).pet.getPetById(...). mode: 'flat' emits a single class named by sdk.name with every operation as a direct method.

Construct a class with a client config, then call a method with the grouped options object ({ path, query, headers, body }). Each call resolves to { status, data, error, contentType, request, response }. Because throwOnError defaults to true, a resolved call means the request succeeded and data is set. Pass throwOnError: false to get the discriminated union instead, keyed on the top-level status:

typescript
const { status, data, error } = await pet.getPetById({ path: { petId: 1 }, throwOnError: false })

if (status === 200) {
  console.log(data) // data is the success body, error is undefined
} else {
  console.error(status, error) // status is the documented error code, error is its parsed body
}

include

Generates only the operations and schemas that match at least one entry, and skips the rest. Each entry filters by tag, operationId, path, method, contentType, or schemaName, with a pattern that can be a string or a RegExp, both matched as a regular expression against the value. A string pattern is compiled with new RegExp(pattern), so it is not an exact match: pattern: 'pet' also matches 'petType' or 'superpet'.

Type definition
typescript
export type Include = {
  type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType' | 'schemaName'
  pattern: string | RegExp
}

exclude

Skips any operation or schema that matches at least one entry, the opposite of include. Entries use the same type and pattern fields as include, and when both options match an item, exclude wins.

override

Applies different plugin options to operations that match a pattern. Each entry takes the same type and pattern as include, plus an options object that accepts any plugin option except override, so rules cannot nest. The first matching entry merges onto the plugin defaults, and later entries do not stack.

Type definition
typescript
export type Override = {
  type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType' | 'schemaName'
  pattern: string | RegExp
  options: Omit<Partial<Options>, 'override'>
}

resolver

Changes how the plugin names generated files and symbols by accepting a partial patch. Override only the members you want, and anything you omit keeps resolverClient. See Override a resolver for the this context and how a patch layers over the default.

TIP

Inside a method this is the full resolver, so this.default.name(name) reuses the built-in casing.

Partial override
typescript
type ResolverClientPatch = {
  name?(name: string): string
  file?: {
    baseName?(params: { name: string; extname: string }): string
    path?(params: { baseName: string; output: Output }): string
  }
  className?(name: string): string
  groupName?(name: string): string     // → 'PetClient'
  propertyName?(name: string): string
}

macros

Rewrites AST nodes before they are printed, without forking the generator. Each macro callback (such as schema or operation) receives the node and a context object, and returns a replacement or undefined to leave it as is. Omitted callbacks keep their defaults, and macros run in order, so a later one sees the output of an earlier one.