Options
Pass these options to pluginFetch(). Shared options link to Shared plugin options, which documents their behavior once.
Options overview
| Option | Purpose | Default |
|---|---|---|
output | Where the generated files are written and exported. | { path: 'clients', barrel: { type: 'named' } } |
↳ output.path | Choose the output folder or file. | 'clients' |
↳ output.mode | Write a single file or a directory of files. | Inferred from output.path |
↳ output.barrel | Configure barrel exports. | { type: 'named' } |
↳ output.banner | Add content before generated code. | None |
↳ output.footer | Add content after generated code. | None |
group | Split output into per-tag or per-path folders. | None |
↳ group.type | Group operations by tag or URL path. | Required with group |
↳ group.name | Customize output group names. | camelCased tag or raw path segment |
baseURL | Base URL prepended to every request. | None |
throwOnErrorDefault | Default error behavior and return type for generated operations. | true |
validator | Validate request and response bodies with Zod. | false |
↳ validator.request | Validate request bodies with Zod. | None |
↳ validator.response | Validate response bodies with Zod. | None |
comments | How much of each description reaches the JSDoc. | 'full' |
sdk | Generate a class-based SDK instead of functions. | None |
↳ sdk.mode | Generate one SDK class per tag or a flat SDK. | 'tag' |
↳ sdk.name | Name the composed or flat SDK class. | None |
returnType | Shape of the value a generated call resolves to. | 'full' |
include | Keep only operations that match. | None |
exclude | Skip operations that match. | [] |
override | Apply different options per pattern. | [] |
resolver | Customize generated names and file paths. | resolverClient |
macros | Rewrite AST nodes before printing. | [], run after the built-in client macros |
Option details
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.
| Type | string |
| Required | false |
throwOnErrorDefault
Set throwOnErrorDefault: false to return documented error responses as values by default. This sets the fallback on each generated request and the default ThrowOnError type parameter on standalone functions and SDK methods. A call with throwOnError: true still throws for a non-2xx response and narrows its return type to successful responses.
| Type | boolean |
| Required | false |
| Default | true |
// pluginAxios({ throwOnErrorDefault: false }) or pluginFetch({ throwOnErrorDefault: false })
const result = await getPetById({ path: { petId: 1 } })
if (result.error) console.error(result.error)This setting applies to the whole plugin and cannot be set in override. Pass throwOnError on a call to override it. Query hooks continue to set throwOnError: true explicitly.
validator
Validates request and response bodies using schemas from @kubb/plugin-zod. Add pluginZod() when either direction uses 'zod'. Invalid bodies cause the generated function to throw a ParseError.
| Type | false | 'zod' | { request?: 'zod'; response?: 'zod' } |
| Required | false |
| Default | false |
import { defineConfig } from 'kubb/config'
import { pluginTs } from '@kubb/plugin-ts'
import { pluginZod } from '@kubb/plugin-zod'
import { pluginFetch } from '@kubb/plugin-fetch'
export default defineConfig({
input: './petStore.yaml',
output: { path: './src/gen' },
plugins: [
pluginTs(),
pluginZod(),
pluginFetch({ validator: { request: 'zod', response: 'zod' } }),
],
})comments
Controls generated JSDoc.
| Type | 'full' | 'brief' | 'none' |
| Required | false |
| Default | 'full' |
sdk
Generates a class-based SDK. Each instance receives a client configuration, so environments can use separate clients. Leave sdk unset to keep the standalone functions used by query plugins.
| Type | { mode?: 'tag' | 'flat'; name?: string } |
| Required | false |
sdk.mode. Generates one class per tag, such as PetClient and StoreClient. Set sdk.name to also generate a root class that instantiates the tag clients from one shared configuration, used as new PetStore(config).pet.getPetById(...).sdk.name, with every operation as a direct method. Supports single-file output.mode: 'tag' needs one file per tag, so pairing it with a single-file output (output.mode: 'file', or an output.path that already names a file such as 'clients.ts') throws KUBB_INVALID_PLUGIN_OPTIONS. Use mode: 'flat' for a single-file SDK, or give output.path a directory so mode: 'tag' can split per tag.
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 }. With the default throwOnErrorDefault: 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:
import { PetClient } from './src/gen/clients/petClient'
const pet = new PetClient({ baseURL: 'https://petstore.swagger.io/v2' })
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
}returnType
Shape of the value a generated call resolves to.
| Type | 'full' | 'data' |
| Required | false |
| Default | 'full' |
{ status, data, error, contentType, request, response }.throwOnError is true. With throwOnError: false, returns the full result so callers can distinguish errors from successful responses.pluginFetch({ returnType: 'data' })
const pet = await getPetById({ path: { petId: 1 } }) // Pet, not { status, data, ... }This applies to the standalone functions and the class-based SDK. @kubb/plugin-react-query, @kubb/plugin-vue-query, @kubb/plugin-swr, and @kubb/plugin-mcp read the same option, so their hooks and tool handlers give you the success body as data either way. They also honor a per-operation returnType set through override.
To read response headers such as ETag under 'data', pass throwOnError: false on the call. It then resolves to the full result, and a non-2xx comes back on error instead of throwing:
const result = await getPetById({ path: { petId: 1 }, throwOnError: false })
if (result.error === undefined) {
const etag = result.response.headers.get('etag')
}resolver
Overrides generated file and symbol names. Omitted members keep resolverClient. The shared members (name, file, imports) and the this context are described under resolver.
| Type | ResolverPatch<ResolverClient> |
| Required | false |
type ResolverClientPatch = {
name?(name: string): string
file?: {
baseName?(params: { name: string; extname: string }): string
path?(params: { baseName: string; output: Output }): string
}
imports?(options: ResolveImportsOptions): Array<ImportNode>
className?(name: string): string
groupName?(name: string): string // → 'PetClient'
propertyName?(name: string): string
}