Beta You're reading the docs for Kubb v5, which is currently in beta. View the stable v4 docs
Skip to content

Configuration

kubb.config.ts drives a Kubb run. The file default-exports a defineConfig call. Pass it an object, a function that returns one, or an array of configs.

kubb.config.ts
typescript
import {  } from 'kubb'

export default ({
  : 'petStore',
  : { : './petStore.yaml' },
  : { : './src/gen' },
})

TIP

defineConfig from the kubb package adds the OpenAPI adapter and the TypeScript parsers for you, so you don't import them yourself.

Config formats

defineConfig accepts an object, a function, or an array.

Single config object

kubb.config.ts
typescript
import {  } from 'kubb'

export default ({
  : 'petStore',
  : { : './petStore.yaml' },
  : { : './src/gen' },
})

Config function

Pass a function when the config depends on the run context, such as watch or logLevel:

kubb.config.ts
typescript
import {  } from 'kubb'

export default (({ ,  }) => ({
  : 'petStore',
  : { : './petStore.yaml' },
  : { : './src/gen', : ! },
}))

The context carries four parameters:

input string Positional input from kubb generate <input>. Overrides config.input.path when set.
watch boolean true in watch mode.
logLevel 'silent' | 'info' | 'verbose' Current log level.
config string Path to the config file in use.

Multiple configurations (array)

Pass an array to generate from several specs in one command:

kubb.config.ts
typescript
import {  } from 'kubb'
import {  } from '@kubb/plugin-ts'

export default ([
  {
    : 'petStore',
    : { : './petStore.yaml' },
    : { : './src/gen/petStore' },
    : [()],
  },
  {
    : 'stripe',
    : { : './stripe.yaml' },
    : { : './src/gen/stripe' },
    : [()],
  },
])

Multiple configurations with a function

Combine the array and function forms:

kubb.config.ts
typescript
import {  } from 'kubb'
import {  } from '@kubb/plugin-ts'

export default (({  }) => [
  {
    : 'petStore',
    : { : './petStore.yaml' },
    : { : './src/gen/petStore', : ! },
    : [()],
  },
  {
    : 'stripe',
    : { : './stripe.yaml' },
    : { : './src/gen/stripe', : ! },
    : [()],
  },
])

Top-level options

name

A name for this config. The CLI prints it as Generating <name>....

Type: string
Required: false

input

Where Kubb reads your spec. Set either path or data, never both. Required when an adapter is configured. Omit it in plugin-only mode, when there is no adapter.

input.path

Local path or URL to your OpenAPI document.

Type: string
Required: true

input.data

OpenAPI spec held in memory, as a string or a parsed object. Use it for programmatic builds.

Type: string | unknown
Required: true

NOTE

When input is set, exactly one of input.path or input.data must be present. input itself is optional in plugin-only mode.

output

Controls where and how files are written.

output.path

Directory for generated files, absolute or relative to root.

Type: string
Required: true

output.mode

How a plugin consolidates its code into files. Set it on a plugin's output, not on the root output.

Type: 'directory' | 'file'
Required: false
Default: 'directory'

'directory' writes one file per operation or schema under output.path. 'file' writes everything into a single file, so output.path must include the extension ('types.ts'). Pair 'directory' with group to split the output into per-tag or per-path subdirectories.

kubb.config.ts
typescript
import {  } from 'kubb'
import {  } from '@kubb/plugin-ts'
import {  } from '@kubb/plugin-axios'

export default ({
  : { : './petstore.yaml' },
  : { : './src/gen' },
  : [
    ({ : { : 'types.ts', : 'file' } }),
    ({ : { : 'clients', : 'directory' }, : { : 'tag' } }),
  ],
})

This writes every type into src/gen/types.ts and one client file per operation, grouped by tag (src/gen/clients/pet/, src/gen/clients/store/).

TIP

mode: 'file' forbids group, since a single file has nothing to group. Pairing them stops the build with a KUBB_INVALID_PLUGIN_OPTIONS error.

output.clean

Wipe output.path before regenerating.

Type: boolean
Required: false
Default: false

WARNING

Only use clean: true with a dedicated output folder. Kubb removes the entire directory.

output.format

Formatter to run on every generated file.

Type: 'auto' | 'prettier' | 'biome' | 'oxfmt' | false
Required: false
Default: false

'auto' detects the first formatter it finds (oxfmt then Biome then Prettier). A named tool forces that one. false skips formatting. Kubb reads your local .prettierrc or biome.json.

output.lint

Linter to run after generation.

Type: 'auto' | 'eslint' | 'biome' | 'oxlint' | false
Required: false
Default: false

'auto' detects the first linter it finds (oxlint then Biome then ESLint). A named tool forces that one. false skips linting.

output.extension

Rewrite the file extensions emitted in import and export statements. Keys are the source extension, values are the output. An empty string drops the extension.

Type: Record<KubbFile.Extname, KubbFile.Extname | ''>
Required: false
Default: { '.ts': '.ts' }

TIP

Use { '.ts': '.js' } for ESM, when the consumer transpiles to JavaScript.

output.barrel

Behavior of the root index.ts barrel file at output.path.

Provided by @kubb/plugin-barrel.

Type: { type: 'all' | 'named' } | false
Required: false
Default: { type: 'named' }

{ type: 'all' } writes export * from '...' for every file. { type: 'named' } writes export { … } from '...' using each file's named exports. false disables the root barrel.

typescript
// src/gen/index.ts
export { CreatePetRequest, Pet } from './pet'
export { User } from './user'
export type { GetPetQuery } from './operations/getPet'
typescript
// src/gen/index.ts
export * from './pet'
export * from './user'
export * from './operations/getPet'
typescript
// no index.ts generated

Each plugin keeps its own output.barrel for its sub-folder and can override the root setting. Setting barrel: false on a plugin disables that plugin's barrel and drops its files from the root barrel. The nested flag works at the plugin level only, where { nested: true } writes a barrel in every subdirectory so callers can import from any depth. The root output.barrel ignores nested.

NOTE

The { type: 'named' } default applies only when pluginBarrel is present in config.plugins. A config that omits pluginBarrel leaves barrel generation untouched.

output.defaultBanner

Auto-generated banner injected at the top of each file.

Type: 'simple' | 'full' | false
Required: false
Default: 'simple'

'simple' adds a short "Generated by Kubb" notice. 'full' adds the notice plus Source, Title, Description, and OpenAPI spec version from the spec. false writes no banner.

typescript
/**
 * Generated by Kubb (https://kubb.dev/).
 * Do not edit manually.
 */
typescript
/**
 * Generated by Kubb (https://kubb.dev/).
 * Do not edit manually.
 * Source: petStore.yaml
 * Title: Pet Store
 * Description: A sample API that uses a petstore as an example.
 * OpenAPI spec version: 1.0.0
 */
typescript
// no banner

output.banner

Text prepended to every file a plugin generates. Set it on an individual plugin. The root output exposes only output.defaultBanner. Use it for license headers, lint-disable comments, or framework directives like 'use server'.

Type: string | ((meta: BannerMeta) => string)
Required: false

A string applies to every file the plugin generates, including barrel (index.ts) and group aggregation ([dir]/[dir].ts) re-export files. A function runs once per file and receives a BannerMeta, so you can vary the banner per file or return an empty string to skip it.

BannerMeta extends the document InputMeta (title, description, version, …) with per-file context:

filePath string Full output path of the file being generated.
baseName string File name only, for example stocks.ts.
isBarrel boolean true for index.ts re-export barrels.
isAggregation boolean true for group [dir]/[dir].ts aggregation files.

The function form fits Next.js Server Actions. Add 'use server' to source files, but skip it on re-export files, which only re-export symbols or return function references and break under the directive.

kubb.config.ts
typescript
import { defineConfig } from 'kubb'
import { pluginAxios } from '@kubb/plugin-axios'

export default defineConfig({
  input: { path: './petStore.yaml' },
  output: { path: './src/gen' },
  plugins: [
    pluginAxios({
      output: {
        path: './clients',
        banner: (meta) => (meta.isBarrel || meta.isAggregation ? '' : "'use server'"),
      },
      group: { type: 'tag' },
    }),
  ],
})

NOTE

Barrel index.ts files stay banner-free by default. They get a banner only when the plugin sets output.banner, at which point the function runs with isBarrel: true.

Text appended to the end of every file a plugin generates. Mirror of output.banner, with the same string \| ((meta: BannerMeta) => string) type.

Type: string | ((meta: BannerMeta) => string)
Required: false

plugins

Array of Kubb plugins. A plugin can declare dependencies, and Kubb throws at startup when one is missing.

Type: Array<KubbUserPlugin>
Required: false
kubb.config.ts
typescript
import {  } from 'kubb'
import {  } from '@kubb/plugin-ts'

export default ({
  : { : './petStore.yaml' },
  : { : './src/gen' },
  : [
    ({
      : { : 'models' },
    }),
  ],
})

adapter

Adapter that converts your input into the universal AST. With defineConfig from the kubb package this defaults to adapterOas() from @kubb/adapter-oas.

Omit adapter (and input) to run in plugin-only mode. Kubb skips spec parsing, but kubb:plugin:setup hooks still fire and injectFile still adds files to the build. Reach for this when a generation script doesn't consume an OpenAPI spec.

See the Adapter concept for the full picture.

Type: Adapter
Required: false
Default: adapterOas() (included with kubb)

Pass options to customize the adapter:

kubb.config.ts
typescript
import {  } from 'kubb'
import {  } from '@kubb/adapter-oas'

export default ({
  : { : './petStore.yaml' },
  : { : './src/gen' },
  : ({ : true }),
})

Plugin-only mode, with no spec and no adapter:

kubb.config.ts (plugin-only)
typescript
import { , ,  } from '@kubb/core'

const  = ({
  : .(),
  : { : './src/gen', : false },
  : [
    (() => ({
      : 'my-file-injector',
      : {
        'kubb:plugin:setup'({  }) {
          ({
            : 'hello.ts',
            : './src/gen/hello.ts',
            : [..({ : [..('export const hello = "world"')] })],
          })
        },
      },
    }))(),
  ],
})
await .()

NOTE

adapterOas() validates OpenAPI specs by default (validate: true). Pass adapterOas({ validate: false }) to skip validation for faster startup or for non-conforming specs.

See the @kubb/adapter-oas reference for every adapter option (validate, contentType, server, discriminator, dateType, integerType, unknownType, emptySchemaType, enumSuffix, …).

parsers

Array of parsers that turn the in-memory file representation into source code. Each parser declares which file extensions it handles through extNames.

See the Parser concept and @kubb/parser-ts for the built-in parsers.

Type: Array<Parser>
Required: false
Default: [parserTs, parserTsx, parserMd] (included with kubb)

Import parsers explicitly to override the default set:

kubb.config.ts
typescript
import {  } from 'kubb'
import { ,  } from '@kubb/parser-ts'

export default ({
  : { : './petStore.yaml' },
  : { : './src/gen' },
  : [, ],
})

Use defineParser from @kubb/core to write your own.

storage

Storage driver that persists generated files. Defaults to fsStorage() (filesystem).

See the Storage concept for the built-in drivers and how to write a custom backend.

Type: Storage
Required: false
Default: fsStorage() (included with kubb)

Use createStorage from @kubb/core to plug in S3, Redis, an in-memory map, or any other backend.

kubb.config.ts
typescript
import {  } from 'kubb'
import {  } from '@kubb/core'

export default ({
  : { : './petStore.yaml' },
  : { : './src/gen' },
  : (),
})

root

Project root, absolute or relative to the config file location.

Type: string
Required: false
Default: process.cwd()

hooks

Lifecycle hooks that run after generation finishes.

hooks.done

Shell command or commands to run when the build finishes, such as a formatter or a test run. Commands run from the root directory, in sequence when you pass an array.

Type: string | Array<string>
Required: false
kubb.config.ts
typescript
import {  } from 'kubb'

export default ({
  : { : './petStore.yaml' },
  : { : './src/gen' },
  : {
    : ['biome check --write ./src/gen'],
  },
})

reporters

Reporters available to the run, registered as instances. defineConfig registers the built-in cli, json, and file reporters by default. The CLI --reporter flag picks which ones fire by name, defaulting to cli when omitted. cli writes the end-of-run summary to the terminal. json writes a machine-readable report to stdout for CI. file writes the run's diagnostics to .kubb/kubb-<name>-<timestamp>.log.

Type: Array<Reporter>
Default: [cliReporter, jsonReporter, fileReporter]
Required: false

Add more reporters to the array, including your own built with createReporter, then select them on the CLI with --reporter <name>.

kubb.config.ts
typescript
import { ,  } from '@kubb/core'
import {  } from 'kubb'

export default ({
  : { : './petStore.yaml' },
  : { : './src/gen' },
  : [, ],
})