Architecture
Kubb turns API specifications into code through a layered pipeline. The adapter parses the spec into a universal AST. Macros rewrite AST nodes before a plugin reads them. Plugins walk the AST and emit FileNodes. Parsers convert each FileNode into source code. Storage writes the result to disk.
Pipeline overview
Config
defineConfig from the kubb package pre-wires adapterOas, the default parsers parserTs, parserTsx, parserMd, and pluginBarrel. A minimal config only needs input and output.
import { } from 'kubb'
export default ({
: { : './petStore.yaml' },
: { : './src/gen' },
: [],
})NOTE
Import from @kubb/core only when you need the lower-level API for programmatic builds or custom tooling.
Adapter
An adapter converts an input specification into the universal AST. adapter.parse(source) returns an InputNode. adapter.getImports(node, resolve) tracks cross-references so plugins emit correct import paths.
Each adapter carries a dialect. The dialect is the one place where spec-specific schema questions live: nullability, $ref resolution, discriminators, binary detection, and schema deduplication. Everything past the adapter is generic JSON Schema, so plugins and parsers never branch on the source format.
The official adapter for OpenAPI 2.0, 3.0, and 3.1 is @kubb/adapter-oas. defineConfig selects it automatically.
import { } from 'kubb'
import { } from '@kubb/adapter-oas'
export default ({
: { : './petStore.yaml' },
: { : './src/gen' },
: ({ : true, : 'date' }),
})See Adapters for the full list of options and details on building a custom adapter.
AST
The AST is the intermediate representation between the adapter and the plugins. Every adapter produces an InputNode; every plugin consumes it. Plugins never read the raw spec, so the same plugin works with any adapter.
InputNode
├── schemas: SchemaNode[] (named, reusable schemas)
│ └── consumed by plugins → FileNode (e.g. type aliases, enums)
└── operations: OperationNode[]
├── parameters: ParameterNode[] → SchemaNode
├── requestBody?: RequestBodyNode → content: ContentNode[] → SchemaNode
├── responses: ResponseNode[] → content: ContentNode[] → SchemaNode
└── consumed by plugins → FileNode (e.g. client functions, hooks)@kubb/ast ships three visitor patterns:
| Visitor | Purpose |
|---|---|
walk(root, visitors) | Async traversal for logging, validation, and side effects. |
transform(root, visitors) | Produces a modified copy of the tree. Return null to remove a node. |
collect(root, visitors) | Gathers matching nodes into a flat array. |
Macros
Macros are the second layer of @kubb/ast. They are named, composable transforms that rewrite schema and operation nodes before a plugin's generators print code. Use them to rename symbols, retype fields, or normalize shapes without forking an adapter or a generator. They run on the shared AST, so the same macro works across every adapter and output target.
Macros run per plugin. One plugin's macros never change the nodes another plugin sees. Pass them through a plugin's macros option, or register them from kubb:plugin:setup with addMacro.
import { } from 'kubb'
import { } from '@kubb/plugin-ts'
import { } from '@kubb/ast/macros'
export default ({
: { : './petStore.yaml' },
: { : './src/gen' },
: [({ : [] })],
})See Macros for writing macros, composing them, and the built-in presets.
Plugins
Plugins walk the AST and emit FileNodes. They run in array order; earlier plugins produce types that later plugins can import.
import { } from 'kubb'
import { } from '@kubb/plugin-ts'
import { } from '@kubb/plugin-axios'
export default ({
: { : './petStore.yaml' },
: { : './src/gen' },
: [(), ()],
})Types and clients
| Package | Generates |
|---|---|
@kubb/plugin-ts | TypeScript types and interfaces |
@kubb/plugin-axios | Axios HTTP client functions |
@kubb/plugin-fetch | Fetch HTTP client functions |
Data-fetching hooks
| Package | Generates |
|---|---|
@kubb/plugin-react-query | TanStack Query hooks for React |
@kubb/plugin-vue-query | TanStack Query hooks for Vue |
Validation and mocking
| Package | Generates |
|---|---|
@kubb/plugin-zod | Zod validation schemas |
@kubb/plugin-faker | Faker.js data factories |
@kubb/plugin-msw | MSW request handlers |
Tooling
| Package | Purpose |
|---|---|
@kubb/plugin-cypress | Cypress test scaffolding |
@kubb/plugin-redoc | Embeds Redoc-rendered API docs |
@kubb/plugin-mcp | Generates MCP-compatible tools and schemas for AI assistants |
See the plugins catalogue for the full list.
Renderer
Plugins can use @kubb/renderer-jsx to describe generated files as React components instead of constructing FileNodes by hand.
NOTE
@kubb/renderer-jsx is optional. Plugins that build FileNodes directly with factory functions from @kubb/ast do not need it.
Parsers
A parser converts a FileNode into a source string. Each parser declares which file extensions it handles. Kubb dispatches every emitted file to the first matching parser.
import { } from 'kubb'
import { , } from '@kubb/parser-ts'
export default ({
: { : './petStore.yaml' },
: { : './src/gen' },
: [, ],
})IMPORTANT
When two parsers claim the same extension, the first one wins.
| Package | Extensions | Description |
|---|---|---|
@kubb/parser-ts | .ts, .js, .tsx, .jsx | Uses the TypeScript compiler to print, deduplicate, and resolve imports. Included automatically with kubb. |
Storage
The storage driver controls where Kubb writes generated files. Default is fsStorage(). Use memoryStorage() for testing, or implement Storage to target any backend.
import { } from 'kubb'
import { } from '@kubb/core'
export default ({
: { : './petStore.yaml' },
: { : './src/gen' },
: (),
})| Driver | Description |
|---|---|
fsStorage() | Writes to disk. Skips unchanged files. Default. |
memoryStorage() | Stores output in a Map. Nothing touches disk. Ideal for tests. |
| Custom | Implement Storage with createStorage to write to S3, a database, or any backend. |
Foundation packages
| Package | Purpose |
|---|---|
kubb | Umbrella package. Exports defineConfig and bundles adapterOas, parserTs, parserTsx, parserMd, and pluginBarrel for a zero-config setup. |
@kubb/core | Lower-level runtime with createKubb, definePlugin, defineParser, createAdapter, and storage APIs. Use for programmatic generation or custom tooling. |
@kubb/cli | Provides the kubb command-line binary. Reads kubb.config.ts and runs the generation pipeline. |
@kubb/ast | Universal AST layer. Includes all node factories, walk, transform, collect, type guards, ref helpers, and the defineDialect and optionality helpers. The macro engine lives on the root and the presets on @kubb/ast/macros. |
@kubb/parser-ts | TypeScript and TSX parser. Included automatically with the kubb package. |
@kubb/renderer-jsx | JSX-based rendering for plugins that build files from React components. |
Build-tool integrations
| Package | Description |
|---|---|
unplugin-kubb | Runs Kubb during your build via unplugin. Works with Vite, Rollup, webpack, esbuild, Rspack, Nuxt, and Astro. |
See the Integrations page for setup instructions for each build tool.
Servers
| Package | Purpose |
|---|---|
@kubb/mcp | Standalone MCP server that lets LLM clients trigger generation directly. |