Plugins
A plugin teaches Kubb to generate something new. It owns:
- its file naming and output folder
- the lifecycle hooks it listens to
- the generators that walk the AST and emit files
Almost everything in a generated src/gen/ folder traces back to one plugin, so how plugins behave is how Kubb behaves.
For the signatures see the Kit API, and to build one step by step follow Creating your first plugin.
TIP
Need a TanStack Query client, a Zod schema set, or MSW handlers? Check the Plugins registry first. Build a custom plugin only when no existing one fits.
What a plugin is
A plugin is a factory. You call it in kubb.config.ts, and it returns an object with a name and a hooks map. The name identifies it, and the hooks decide which moments of a build it cares about.
Each plugin keeps to its own corner:
- registers generators that walk the AST
- declares a resolver that names and places its files
- reads only the options it was given
That isolation is what makes a build predictable. The TypeScript plugin never touches the Zod plugin's state, and either one drops in or out without disturbing the other.
How the lifecycle runs
A build moves through phases in a fixed order, and each plugin subscribes only to the moments it cares about.
- Setup runs first, once per plugin, before any code exists. Validate options here and fail fast on a missing one.
- Kubb walks the AST and calls your generator handlers for every schema and operation node. Most
FileNodes come from here. - A closing event hands each plugin a snapshot of what it produced.
- One last event fires before anything hits disk, the spot to add aggregate files like a barrel.
- Writing, formatting, and linting follow.
The lifecycle hooks reference lists every hook, its payload, and when it fires.
How plugins compose
Plugins rarely work alone. A client plugin leans on the types a TypeScript plugin already generated, and a mock plugin reuses the same schemas. Kubb gives them two ways to cooperate without hard-coding paths or guessing at order:
- Dependencies let a plugin name the other plugins it needs. Kubb runs those first and fails the build with a clear error when one is missing, so you never order the
pluginsarray by hand. - Resolvers let a plugin read another plugin's file names and paths by plugin name, so imports stay correct even when naming rules change.
Post-enforced plugins
Most plugins run in one normal pass, but some need to see what everyone else produced first. A barrel generator can only write its index files once the other plugins have emitted what it re-exports. Setting a plugin's enforce field moves it to the front or the back of every event it listens to, though a declared dependency always runs first regardless. @kubb/plugin-barrel is the one to read when this fits your case.
Built-in plugins
The Kubb monorepo ships official plugins for the most common cases. Browse them in the Plugins registry.
| Plugin | Generates |
|---|---|
@kubb/plugin-ts | TypeScript types from your spec. |
@kubb/plugin-zod | Zod schemas. |
@kubb/plugin-axios | Type-safe axios client functions. |
@kubb/plugin-fetch | Type-safe Fetch client functions. |
@kubb/plugin-react-query | React Query (TanStack) hooks. |
@kubb/plugin-vue-query | Vue Query (TanStack) hooks. |
@kubb/plugin-msw | MSW request handlers. |
@kubb/plugin-faker | Faker-based mock data. |
@kubb/plugin-cypress | Cypress request helpers. |
@kubb/plugin-mcp | MCP tool definitions. |
@kubb/plugin-redoc | Redoc API documentation. |
Next steps
To build a plugin, work through Creating your first plugin. For the exact shape of definePlugin, defineGenerator, createResolver, and the context passed to each hook, read the Kit API. To retune the names and file paths a plugin produces without writing one, see Override a resolver.