---
layout: doc
title: Release of Kubb 5.0
description: Kubb 5.0 rebuilds code generation around adapters, a universal AST, parsers, and storage, and generates code up to 5.4x faster than v4.
outline: deep
image: /blog/v5/cover.svg
date: 2026-08-20
---

> Index of every page on this site: [llms.txt](https://kubb.dev/llms.txt)

::confetti-burst
::

![Release of Kubb 5.0](/blog/v5/cover.svg)

# Introducing Kubb v5

Kubb generates TypeScript types, an Axios or Fetch client, Zod schemas, TanStack Query hooks, Faker mocks, and MSW handlers from an OpenAPI spec. v5 rewrites how it does that. One [adapter](/docs/5.x/explanation/architecture#adapters) parses your spec into a universal [AST](/docs/5.x/explanation/architecture#ast), plugins walk that AST, [parsers](/docs/5.x/explanation/architecture#parsers) turn the result into source code, and [storage](/docs/5.x/explanation/architecture#storage) writes it to disk.

You feel that rewrite in three places: your config gets shorter, your generated client calls change shape, and generation runs more than five times faster. The sections below show each one. For a before and after on every breaking change, read the [migration guide](/docs/5.x/how-to/migration).

::stat-highlights
---
items:
  - value: 5.4
    prefix: "up to "
    suffix: ×
    label: faster than v4
  - value: 1
    label: shared AST, parsed once
  - value: 288
    label: OpenAI operations in 3.4s
---
::

## Up to 5.4x faster generation

The [OpenAI spec](https://github.com/openai/openai-openapi) is 288 operations across 2.9 MB. Generating types, an Axios client, Zod schemas, and Faker mocks from it took 18.4 seconds in v4. v5 does the same work in 3.4 seconds.

::speed-comparison
::

Each run uses `plugin-ts` with the Axios, Zod, and Faker plugins, median of five runs, both versions writing to disk.

Two changes explain the gap. In v4 every plugin bootstrapped its own OpenAPI parser, so a config with four plugins read the same spec four times. In v5 the adapter parses it once and hands the same AST to every plugin. The renderer changed too: v5 prints synchronously and drops the React runtime that v4 loaded to render files. The larger the spec, the more that parse-once saving compounds, which is why the OpenAI numbers move the most.

The full tables, one per plugin combination, live in the [migration guide](/docs/5.x/how-to/migration).

## A smaller config

v4 read the spec through a `pluginOas` entry in the plugins array, and every schema plugin repeated the same schema options like `dateType` and `integerType`. v5 moves spec reading to a top-level `adapter` and the schema options along with it, so each plugin keeps only what it generates.

::code-group

```typescript [v4 kubb.config.ts]
import { defineConfig } from '@kubb/core'
import { pluginOas } from '@kubb/plugin-oas'
import { pluginTs } from '@kubb/plugin-ts'
import { pluginFaker } from '@kubb/plugin-faker'

export default defineConfig({
  input: { path: './petStore.yaml' },
  output: { path: './src/gen' },
  plugins: [
    pluginOas({ validate: true }),
    pluginTs({ dateType: 'date', integerType: 'number' }),
    pluginFaker({ dateType: 'date', integerType: 'number' }),
  ],
})
```

```typescript twoslash [v5 kubb.config.ts]
import { defineConfig } from 'kubb/config'
import { adapterOas } from '@kubb/adapter-oas'
import { pluginTs } from '@kubb/plugin-ts'
import { pluginFaker } from '@kubb/plugin-faker'

export default defineConfig({
  input: './petStore.yaml',
  output: { path: './src/gen' },
  adapter: adapterOas({ validate: true, dateType: 'date', integerType: 'number' }),
  plugins: [pluginTs(), pluginFaker()],
})
```

::

`defineConfig` now comes from the `kubb/config` subpath. It pre-wires the OpenAPI adapter, the TypeScript and Markdown parsers, and the barrel plugin, so the `adapter` line above is only needed when you pass options. `input` also collapsed to a single value: give it a path, a URL, an inline spec, or a parsed object, and Kubb works out which it is.

## One pipeline, from spec to files

Every run flows through one [pipeline](/docs/5.x/explanation/architecture), and the easiest way to see it is to follow a single `getPet` operation. The adapter reads it from the spec and turns it into an AST node that no longer mentions OpenAPI. The plugins walk that node in order: `@kubb/plugin-ts` writes the `Pet` type, `@kubb/plugin-axios` writes the `getPet` function that imports it, `@kubb/plugin-zod` writes the schema. A parser prints each file, `@kubb/parser-ts` for the TypeScript output and the new `@kubb/parser-md` for Markdown straight from the spec. Storage writes them out and skips any file that has not changed.

The adapter is the only layer that knows the source was OpenAPI, so the same plugins would run unchanged on an AsyncAPI or GraphQL adapter later. Every plugin in the suite, from TypeScript and Zod to MSW and TanStack Query, runs on this pipeline.

## What changes in your generated client

Two changes reach every client call. Functions used to spread parameters across positional arguments. In v5 they take one grouped object, `{ body, path, query, headers }`, with camelCase names that Kubb maps back to the wire names for you. The client also returns a `RequestResult` with `status`, `data`, `error`, `contentType`, `request`, and `response`. `throwOnError` defaults to `true`, so the common path is a destructure:

```diff [Calling the client]
- const pet = await getPet(1)
+ const { data: pet } = await getPet({ path: { petId: 1 } })
```

Set `throwOnError: false` when you would rather read `error` and `response.status` off the result than catch. Operations that declare more than one request body content type now generate one type per content type plus a union alias, where v4 kept only the first.

## Upgrading

The [migration guide](/docs/5.x/how-to/migration) carries a before and after for every change, in the core config and in each plugin. It opens with an upgrade prompt: paste it into any LLM along with your `kubb.config.ts` and it handles most of the config for you.

> [!IMPORTANT]
> Check your Node version first, since v5 needs version 22 or later.

If you hit anything unexpected, open an issue on [GitHub](https://github.com/kubb-labs/kubb/issues).

Kubb is open source and community-driven. If v5 helps your team, consider [sponsoring the project](https://github.com/sponsors/stijnvanhulle).

👋🏽 [Stijn Van Hulle](https://twitter.com/stijnvanhulle)

## Sitemap

See the full [sitemap](https://kubb.dev/sitemap.md) for all pages.
