Open Studio
Kit

Engine and configuration

The engine that runs your plugins comes from the kubb package and its kubb/config subpath. Covers defineConfig, createKubb, the Kubb instance, BuildOutput, and narrowing config.input.

The engine that runs your plugins comes from the kubb package and its kubb/config subpath. This page documents that surface: defineConfig, createKubb, and the build types they share.

defineConfig ​

defineConfig adds TypeScript type-checking to a kubb.config.ts file. It comes from the kubb package and fills in defaults for any field you omit.

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

export default defineConfig({
  input: './petStore.yaml',
  output: { path: './src/gen' },
})

It accepts a config object, an array of configs, a Promise, or a function. The function form receives the CLI options at runtime, so you can toggle behavior on flags like --watch:

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

export default defineConfig(({ watch }) => ({
  input: './petStore.yaml',
  output: { path: './src/gen', clean: !watch },
}))

Defaults applied for omitted fields ​

FieldDefault
rootprocess.cwd()
adapteradapterOas()
parsers[parserTs(), parserTsx(), parserMd()]
reporters[cli, json, file]
pluginspluginBarrel() appended when not already present
output.barrelfalse (barrel generation is opt-in, even with pluginBarrel in plugins)
output.formatfalse
output.lintfalse

Important

defineConfig comes from the kubb package. Import it from kubb or the kubb/config subpath.

Tip

pluginBarrel generates nothing until output.barrel is set, root or per-plugin. A plugins list without pluginBarrel leaves barrel generation untouched.

createKubb ​

createKubb drives Kubb from your own code. It accepts a UserConfig and returns a Kubb instance. Calling .build() runs the full generation pipeline and returns a BuildOutput.

Reach for createKubb when you orchestrate several builds, inspect diagnostics, or feed Kubb output into a larger toolchain. For a one-off build, chain the call: await createKubb(config).build().

Import createKubb from the kubb package. It applies the same defaults as defineConfig, so a shared config has the same adapter, parsers, and plugins in both paths. Import it from @kubb/core when you need a bare engine without package defaults.

createKubb takes a plain config object, the same shape defineConfig produces in kubb.config.ts, not a fluent builder. The config stays plain, serializable data so Kubb can validate it against the shipped JSON schema.

build.ts
typescript
import { createKubb } from 'kubb'
import { Diagnostics } from 'kubb/kit'
import { pluginTs } from '@kubb/plugin-ts'
import { pluginAxios } from '@kubb/plugin-axios'

const kubb = createKubb({
  input: './petStore.yaml',
  output: { path: './gen' },
  plugins: [pluginTs(), pluginAxios()],
})

const { files, storage, driver, diagnostics } = await kubb.safeBuild()

if (Diagnostics.hasError(diagnostics)) {
  for (const diagnostic of diagnostics.filter(Diagnostics.isProblem)) {
    if (diagnostic.severity === 'error') {
      console.error(`${diagnostic.plugin ?? 'kubb'}: ${diagnostic.message}`)
    }
  }
  process.exit(1)
}

// Per-plugin timings are carried as `performance` diagnostics.
for (const { plugin, duration } of diagnostics.filter(Diagnostics.isPerformance)) {
  console.log(`${plugin}: ${duration}ms`)
}
console.log(`Generated ${files.length} files`)
const paths = await storage.readKeys()
paths.forEach((path) => console.log(`  ${path}`))

Kubb instance members (all getters are read-only) ​

MemberTypeDescription
.setup()() => Promise<void>Initializes the driver and storage. build() calls this automatically.
.build()() => Promise<BuildOutput>Runs the full pipeline and throws a BuildError when any diagnostic is an error.
.safeBuild()() => Promise<BuildOutput>The canonical call. Runs the full pipeline and collects problems in BuildOutput.diagnostics instead of throwing.
.hooksHookable<KubbHooks>Read-only. Shared hook emitter. Call .hook(name, handler) before build() to attach a listener. See lifecycle hooks.
.configConfigRead-only. Resolved config, available right after createKubb since it resolves in the constructor.
.storageStorageRead-only getter. Final source code keyed by absolute path. Available after setup(), throws before.
.driverread-only getterAdvanced plugin driver handle, available after setup(). Throws if accessed before setup().

BuildOutput fields ​

FieldTypeDescription
filesArray<FileNode>Generated files with paths, names, and content
storageStorageGenerated source code accessible via the Storage API
driverdriver handleAdvanced plugin driver handle for introspection
diagnosticsArray<Diagnostic>Problems collected during the build, plus a performance diagnostic per plugin

Each Diagnostic carries a code, a severity (error, warning, or info), a message, and the plugin that produced it. Failed-plugin diagnostics keep the original error on cause. A performance diagnostic (kind: 'performance') carries a duration in milliseconds. Use the Diagnostics.isProblem, Diagnostics.isPerformance, and Diagnostics.isUpdate guards to narrow by kind.

Warning

After safeBuild(), check Diagnostics.hasError(diagnostics) before processing files. Plugins can fail without safeBuild() throwing. build() throws a BuildError in that case.