Skip to content
Reference

Options

Configuration options for @kubb/plugin-ts.
OptionTypeDefaultDescription
outputOutput{ path: 'types', barrel: { type: 'named' } }Where the generated files are written and exported
groupGroup—Split output into per-tag or per-path folders
enumEnumOptions{ type: 'asConst', … }How enums are generated and cased
syntaxType'type' | 'interface''type'Emit object schemas as type aliases or interfaces
optionalType'questionToken' | 'undefined' | 'questionTokenAndUndefined''questionToken'How optional properties are written
arrayType'array' | 'generic''array'Type[] or Array<Type>
includeArray<Include>—Keep only operations that match
excludeArray<Exclude>[]Skip operations that match
overrideArray<Override>[]Apply different options per pattern
resolverResolverPatch<ResolverTs>—Customize generated names and file paths
macrosArray<Macro>—Rewrite AST nodes before printing
printer{ nodes?: PrinterTsNodes }—Replace the handler for a schema type

output

Where the generated .ts files are written and how they are exported.

output.path

Folder where the plugin writes its files (string, default 'types'), resolved against the global output.path on defineConfig.

output.mode

How generated code is consolidated into files.

  • 'file' writes everything into a single file, so output.path needs a file extension such as 'types.ts'.
  • 'directory' writes one file per operation or schema under output.path.

Leave it unset and Kubb reads output.path: a name with an extension means one file, anything else a directory.

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
export { Pet, User } from './models'
export { getPetById, getInventory } from './clients'

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. Kubb reads the plugin's own output.barrel first, falls back to config.output.barrel on defineConfig, and finally to false. Every generator plugin ships a default output that sets barrel: { type: 'named' }, but passing your own output replaces that object wholesale, so repeat barrel whenever you set output yourself.

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'.

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

Turns a group key into a folder or identifier name, used as the subdirectory name and as a suffix on aggregate files. Type (context: { group: string }) => string, default ({ group }) => camelCase(group), which for type: 'path' groups uses the first URL segment as-is instead of camelCasing.

enum

How OpenAPI enums are represented in the generated TypeScript, and how their names are cased.

enum.type

Representation of each enum. Defaults to 'asConst'.

  • 'asConst' emits an as const object plus a key/value type. Tree-shakeable, with no runtime.
  • 'enum' emits a TypeScript enum with JavaScript runtime code.
  • 'constEnum' emits a const enum, inlined at compile time and incompatible with --isolatedModules.
  • 'literal' emits a union type with no runtime value.
  • 'inlineLiteral' inlines the union at each usage site instead of giving it a name.
export const petStatus = {
  available: 'available',
  pending: 'pending',
  sold: 'sold',
} as const

export type PetStatusKey = (typeof petStatus)[keyof typeof petStatus]

enum.constCasing

Casing of the generated const variable when type is 'asConst'. Defaults to 'camelCase'.

  • 'camelCase' names the const petStatus.
  • 'pascalCase' names the const PetStatus, matching the schema name.
export const petStatus = {
  available: 'available',
  pending: 'pending',
  sold: 'sold',
} as const

export type PetStatusKey = (typeof petStatus)[keyof typeof petStatus]

enum.typeSuffix

Suffix on the type alias generated when type is 'asConst' (string, default 'Key'), applied only to the companion type alias, not the const object name. Set it to '' to drop the suffix, which with constCasing: 'pascalCase' merges the const and type under one name.

export const petStatus = {
  available: 'available',
  pending: 'pending',
  sold: 'sold',
} as const

export type PetStatusKey = (typeof petStatus)[keyof typeof petStatus]

enum.keyCasing

Casing applied to enum key names, 'none' by default (the raw value from the spec).

ValueExample key
'screamingSnakeCase'ENUM_VALUE
'snakeCase'enum_value
'pascalCase'EnumValue
'camelCase'enumValue
'none' (default)as-is

syntaxType

Whether object schemas are emitted as type aliases or interface declarations, with type as the safer default. Pick interface only when consumers need declaration merging, which is rare for generated code and covered in Type vs Interface.

export type Pet = {
  name: string
}

optionalType

How optional properties are written. Defaults to 'questionToken'.

  • 'questionToken' writes type?: string, so the property may be missing.
  • 'undefined' writes type: string | undefined, so it must exist but may be undefined.
  • 'questionTokenAndUndefined' writes type?: string | undefined, the strictest form. Use it with "exactOptionalPropertyTypes": true.
export type Pet = {
  type?: string
}

arrayType

Syntax for array types. Defaults to 'array'.

  • 'array' uses the postfix Type[].
  • 'generic' uses Array<Type>, which reads better for complex elements like Array<{ id: number }>.
export type Pet = {
  tags: string[]
}

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
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.

When operations are excluded on a client plugin (@kubb/plugin-fetch or @kubb/plugin-axios), dependent plugins (@kubb/plugin-react-query, @kubb/plugin-vue-query, @kubb/plugin-swr, @kubb/plugin-mcp) skip generating hooks or handlers for those operations automatically, without requiring duplicate exclude configurations.

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
export type Override = {
  type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType' | 'schemaName'
  pattern: string | RegExp
  options: Omit<Partial<Options>, 'override'>
}

When options such as returnType, output, or group are overridden on a client plugin (@kubb/plugin-fetch or @kubb/plugin-axios), dependent plugins (@kubb/plugin-react-query, @kubb/plugin-vue-query, @kubb/plugin-swr, @kubb/plugin-mcp) resolve and follow those per-operation options automatically.

resolver

Overrides generated file and symbol names. Omitted members keep the plugin's resolver defaults. See Override a resolver for the this context and how a patch layers over the default.

Inside a method this is the full resolver, so this.default.name(name) reuses the built-in casing.
Partial override
type ResolverTsPatch = {
  name?(name: string): string
  file?: {
    baseName?(params: { name: string; extname: string }): string
    path?(params: { baseName: string; output: Output }): string
  }
  param?: {
    name?(node: OperationNode, param: ParameterNode): string    // → 'DeletePetPathPetId'
    path?(node: OperationNode, param: ParameterNode): string     // → 'GetPetByIdPath'
    query?(node: OperationNode, param: ParameterNode): string    // → 'FindPetsByStatusQuery'
    headers?(node: OperationNode, param: ParameterNode): string  // → 'DeletePetHeaders'
  }
  response?: {
    status?(node: OperationNode, statusCode: StatusCode): string // → 'ListPetsStatus200'
    options?(node: OperationNode): string                        // → 'ListPetsOptions'
    responses?(node: OperationNode): string                      // → 'ListPetsResponses'
    response?(node: OperationNode): string                       // → 'ListPetsResponse'
    body?(node: OperationNode): string                           // → 'CreatePetBody'
  }
  enum?: {
    keyName?(node: { name?: string | null }, enumTypeSuffix?: string): string // → 'PetStatusKey'
  }
}

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.

printer

Replaces the node handler for a schema type such as 'integer' or 'date' with one that builds its TypeScript AST node. Use this.transform to recurse into nested nodes and this.options to read printer options. The printer guide covers the handler context and how overrides compose with macros.

Map date schemas to the Date object
import ts from 'typescript'
import { pluginTs } from '@kubb/plugin-ts'

pluginTs({
  printer: {
    nodes: {
      date() {
        return ts.factory.createTypeReferenceNode('Date', [])
      },
      integer() {
        return ts.factory.createKeywordTypeNode(ts.SyntaxKind.BigIntKeyword)
      },
    },
  },
})