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

Kit API

kubb/kit is the authoring toolkit for extending Kubb: plugins, generators, resolvers, parsers, adapters, renderers, and storage backends all start here. It is a subpath of the top-level kubb package, backed by the @kubb/kit package, so there is nothing extra to install. Import straight from kubb/kit.

imports.ts
typescript
import {
  ,
  ,
  ,
  ,
  ,
  ,
  ,
  ,
  ,
  ,
  ,
  ,
} from 'kubb/kit'

TIP

The build-time engine (createKubb, KubbDriver, reporters) stays on @kubb/core. kubb/kit is only for the authoring side: the code you write to add a new plugin, generator, resolver, parser, adapter, or renderer.

Plugin authoring

Plugins are the main extension point in Kubb. A plugin owns its file naming, its output folder, its lifecycle hooks, and the generators that walk the AST and emit FileNode objects.

definePlugin

definePlugin wraps a factory function and returns a typed Plugin. All lifecycle handlers live under one hooks object, inspired by Astro integrations.

plugin-example.ts
typescript
import {  } from 'kubb/kit'

export const  = ((: { ?: string } = {}) => ({
  : 'plugin-example',
  : {
    'kubb:plugin:setup'() {
      // Register resolvers, generators, and options here.
    },
  },
}))

Plugin shape

Property Type Required Description
name string Yes Unique plugin identifier (e.g., plugin-ts)
dependencies Array<string> No Names of other plugins this one requires
options unknown No User-supplied options passed through to generators
hooks { 'kubb:plugin:setup'?: ...; ... } Yes Lifecycle handlers (see Plugin API)

KubbPluginSetupContext methods (passed to kubb:plugin:setup)

Method Signature Purpose
addGenerator (...generators: Array<Generator>) => void Register one or more generators for this plugin
setResolver (resolver: Partial<Resolver>) => void Set or partially override the file naming resolver
addMacro (macro: Macro) => void Add a macro that rewrites AST nodes before generators
setMacros (macros: Array<Macro>) => void Replace this plugin's macros with a new list
setOptions (options: ResolvedOptions) => void Set the resolved options used by generators
injectFile (file: UserFileNode) => void Inject a raw file into the build output, bypassing generation
updateConfig (config: Partial<Config>) => void Merge a partial config update into the current build config
config Config The resolved build configuration at setup time
options TOptions The plugin's own options as passed by the user

IMPORTANT

Plugin names should follow the convention plugin-<feature> (e.g., plugin-react-query, plugin-zod). See Creating plugins for naming conventions.

defineGenerator

defineGenerator declares a named generator unit consumed by a plugin. Generators walk the AST and emit files. The core calls each method for the matching node type during the generation loop.

Each generator method returns TElement | Array<FileNode> | void. Returning a renderer element (for example JSX from kubb/jsx) requires a renderer factory on the generator. Returning Array<FileNode> directly, or calling ctx.upsertFile() and returning void, works without a renderer.

my-generator.ts
typescript
import { ,  } from 'kubb/kit'

const  = ({
  : 'my-generator',
  (, ) {
    return [
      ..({
        : `${.}.ts`,
        : `./${.}.ts`,
        : [
          ..({
            : [..(`export const op = '${.}'`)],
          }),
        ],
      }),
    ]
  },
})

Generator methods

Method Input Output When to use
schema() SchemaNode (per data schema) TElement | Array<FileNode> | void Generate types, validators, factories. Called once per schema
operation() OperationNode (per API operation) TElement | Array<FileNode> | void Generate hooks, clients, handlers. Called once per operation
operations() Array<OperationNode> (all operations) TElement | Array<FileNode> | void Generate index or barrel files. Called once after all operations

GeneratorContext properties (the ctx argument passed to each method)

Property Type Purpose
ctx.config Config Resolved Kubb configuration
ctx.root string Absolute path to the output directory for the current plugin
ctx.options TResolvedOptions Per-node resolved options (after exclude/include/override filtering)
ctx.plugin Plugin The owning plugin descriptor
ctx.resolver Resolver Resolver for the current plugin
ctx.driver KubbDriver Plugin driver for cross-plugin access
ctx.hooks AsyncEventEmitter<KubbHooks> Event bus for KubbHooks events
ctx.adapter Adapter The adapter that parsed the input spec
ctx.meta InputMeta Document metadata from the adapter. Carries title, version, baseURL, and the pre-computed circularNames and enumNames arrays.
ctx.addFile() (...files: FileNode[]) => Promise<void> Add files, skipping any that already exist
ctx.upsertFile() (...files: FileNode[]) => Promise<void> Add or merge files (concatenates sources and imports)
ctx.getPlugin() (name: string) => Plugin | undefined Get a plugin by name
ctx.requirePlugin() (name: string) => Plugin Get a plugin by name or throw a descriptive error
ctx.getResolver() (name: string) => Resolver Get a resolver by plugin name
ctx.info() (message: string) => void Emit an info message via the build event system
ctx.warn() (message: string) => void Emit a warning via the build event system
ctx.error() (error: string | Error) => void Emit an error via the build event system

TIP

Return an empty array [] to skip a node without error. Return void to handle file writing manually via ctx.upsertFile().

defineResolver

defineResolver creates a resolver that controls file naming and path resolution for a plugin. The builder is a zero-argument function. Use this to call sibling resolver methods.

The builder must return at least { name, pluginName }. The other resolver methods (default, resolveOptions, resolvePath, resolveFile, resolveBanner, resolveFooter) receive built-in defaults and can each be overridden.

resolver.ts
typescript
import {  } from 'kubb/kit'
import type { ,  } from 'kubb/kit'

// Extend the base Resolver with plugin-specific naming methods.
type  =  & {
  (: { : string }): string
}

type  = <'plugin-example', object, object, >

export const  = <>(() => ({
  : 'default',
  : 'plugin-example',
  () {
    return this.(., 'function')
  },
}))

Auto-injected resolver defaults

Method Default behavior
default camelCase for function/file, PascalCase for type
resolveOptions Applies exclude, include, and override filters
resolvePath Resolves to output.path, with optional tag/path-based subdirectories
resolveFile Constructs a full FileNode using default + resolvePath
resolveBanner Returns output.banner or the standard "Generated by Kubb" header
resolveFooter Returns output.footer when set

defineParser

defineParser creates a parser that converts generated file ASTs to formatted source strings. Each parser declares which file extensions it handles via extNames.

The built-in parsers handle TypeScript, TSX, and markdown files: parserTs, parserTsx, and parserMd. Implement defineParser to add other languages or custom output formats.

createAdapter

createAdapter builds adapters that translate non-OpenAPI specs into Kubb's universal AST. The built-in @kubb/adapter-oas handles OpenAPI and Swagger documents.

Write a custom adapter when your source is something Kubb does not parse yet, such as a GraphQL schema, a gRPC definition, an AsyncAPI spec, or your own domain-specific language.

IMPORTANT

Adapters must parse their input format to Kubb's InputNode structure. See Adapter API for complete documentation.

Rendering

createRenderer

createRenderer takes a builder function and returns a factory that produces a Renderer, the object a generator's renderer field points at. It follows the same builder-to-factory shape as createStorage: call the builder once, get back a reusable factory, call the factory to get an instance.

Reach for createRenderer when a generator needs to emit something other than plain FileNode arrays or kubb/jsx elements, for example a renderer that walks a different templating format into FileNodes. kubb/jsx's own jsxRenderer ships as a plain factory and does not depend on createRenderer, so most plugin authors only need createRenderer when they are building an alternative to JSX rendering.

Storage

Storage backends decide where generated files are written. Kubb ships a filesystem backend and an in-memory one. Use createStorage to build your own.

createStorage

createStorage takes a builder function (options: TOptions) => Storage and returns a factory (options?: TOptions) => Storage. Call the returned factory to instantiate the storage, optionally with options.

memory-storage.ts
typescript
import {  } from 'kubb/kit'

export const  = (() => {
  const  = new <string, string>()
  return {
    : 'memory',
    async () {
      return .()
    },
    async () {
      return .() ?? null
    },
    async (, ) {
      .(, )
    },
    async () {
      .()
    },
    async () {
      const  = [....()]
      return  ? .(() => .()) : 
    },
    async () {
      if (!) return .()
      for (const  of .()) if (.()) .()
    },
    async () {
      .()
    },
  }
})

TIP

Use memoryStorage for tests and dry runs. Use fsStorage for normal development and CI/CD.

The Storage interface itself (hasItem, getItem, setItem, removeItem, getKeys, clear, dispose) is documented on the engine reference, since Storage describes something the engine consumes, not something kubb/kit defines.

fsStorage

fsStorage is the built-in filesystem storage backend. Kubb uses it by default when no storage option is set in the config. It creates output directories automatically and respects output.path.

memoryStorage

memoryStorage is the built-in in-memory storage backend. It writes nothing to disk, so it suits plugin tests, CI validation, and dry runs.

NOTE

Both fsStorage and memoryStorage are exported from kubb/kit and can be passed directly to the storage field at the root of your config.

AST and node builders

ast

ast is kubb/kit's re-export of the entire @kubb/ast module, the same way TypeScript groups its node constructors under ts.factory. Reach for ast when you also need the visitors (ast.walk, ast.transform, ast.collect), the guards, or the schema and string helpers alongside node construction.

ast-namespace.ts
typescript
import {  } from 'kubb/kit'

const  = ..({
  : [..({ : 'Pet', : 'object', : [] })],
  : [],
})

factory

factory is the bare node-builder namespace, equivalent to ast.factory but importable on its own when a generator only needs to construct nodes and does not need the rest of @kubb/ast.

factory-namespace.ts
typescript
import {  } from 'kubb/kit'

const  = .({
  : 'pet.ts',
  : './pet.ts',
  : [.({ : [.("export type Pet = { id: number }")] })],
})

ast.factory.createX(...) and the bare factory.createX(...) construct the same nodes. Pick whichever import reads better in the file: ast.factory when the file already uses ast.walk or ast.transform nearby, factory on its own when node construction is the only thing the file does.

  • AST concepts for the full mental model of the AST, its node kinds, and traversal
  • AST API reference for every factory, visitor, and guard @kubb/ast exports

Diagnostics

Diagnostics

Diagnostics is the namespace a plugin or adapter uses to build and narrow the structured errors Kubb collects during a build. Throw or return a Diagnostics.Error instead of a bare Error when you want a stable code, a severity, and a location attached.

Member Purpose
Diagnostics.Error Constructs a diagnostic-carrying error with a code, severity, and message
Diagnostics.hasError Narrows an array of diagnostics to whether any has severity: 'error'
Diagnostics.isProblem Guards a diagnostic down to the problem kind (as opposed to performance or update)

See the Diagnostics reference for the full list of stable codes Kubb ships with, and how Diagnostics.hasError and Diagnostics.isProblem are used together after a build.

Public types

kubb/kit re-exports the types that go with plugin, generator, resolver, adapter, and renderer authoring. Import them alongside the functions above to type your own code. Config and UserConfig, the overall build configuration shapes, stay on @kubb/core, since createKubb and defineConfig are the engine's entry points.

Plugins

Type Purpose
Plugin Final plugin object returned from definePlugin
PluginFactoryOptions Generic parameter pack used to type a plugin
KubbPluginSetupContext Context passed to kubb:plugin:setup
KubbHooks Map of every lifecycle event the driver emits

Generators

Type Purpose
Generator Generator object returned from defineGenerator
GeneratorContext Context passed to schema(), operation(), and operations() methods

Resolvers

Type Purpose
Resolver Base constraint for resolvers returned from defineResolver
ResolverContext Shared context for path, file, and name resolution
ResolverPathParams Parameters for Resolver.resolvePath
ResolverFileParams Parameters for Resolver.resolveFile
ResolveBannerContext Context for banner and footer resolution (output, config, per-file file)
ResolveBannerFile Per-file context (path, baseName, isBarrel, isAggregation)
BannerMeta InputMeta extended with per-file fields, passed to a banner or footer function
ResolveOptionsContext Context for resolveOptions (include, exclude, override)

Adapters and parsers

Type Purpose
Adapter Final adapter object returned from createAdapter
AdapterFactoryOptions Generic parameter pack for an adapter
AdapterSource { type: 'path'; path } or { type: 'data'; data }
Parser Final parser object returned from defineParser

Rendering

Type Purpose
Renderer / RendererFactory Interfaces for custom renderers set on a generator's renderer field

Output and filters

Type Purpose
Output Per-plugin output configuration
OutputMode 'directory' | 'file'
OutputOptions Output plus a group strategy
Group Grouping strategy for generated files
Include Filter narrowing generation to matching nodes
Exclude Filter preventing matching nodes from being generated
Override Filter pairing a match with per-node option overrides

Testing

kubb/kit/testing is a separate subpath for the Vitest-backed helpers used to test plugins, generators, and adapters. It stays separate from kubb/kit so importing the authoring toolkit never pulls Vitest into a plugin's runtime dependencies.

plugin.test.ts
typescript
import { , ,  } from 'kubb/kit/testing'

createMockedPlugin and createMockedAdapter build a minimal plugin or adapter for a test without wiring a full config. createMockedPluginDriver builds a driver around a set of plugins so a generator can run through its real lifecycle in isolation. renderGeneratorSchema, renderGeneratorOperation, and renderGeneratorOperations call a generator's schema(), operation(), or operations() method directly against a node fixture and return the resulting files. matchFiles asserts a set of generated FileNodes matches expected paths and contents, the assertion most generator tests end on.

See also

  • Core API for the engine: createKubb, KubbDriver, storage, reporters, and the file pipeline
  • AST API reference for the full @kubb/ast surface behind kubb/kit's ast and factory
  • JSX API reference for kubb/jsx, the JSX renderer
  • Plugin concepts for lifecycle hooks, generators, resolvers, and the plugin registry
  • Creating plugins for a step-by-step guide to building a full plugin