Skip to content

Recipes ​

Ready-made kubb.config.ts snippets for common setups. Copy one in, install the matching packages, and run kubb generate.

TypeScript only ​

The smallest setup, generating TypeScript types and interfaces from your OpenAPI spec.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
export default
defineConfig
({
input
: './petStore.yaml',
output
: {
path
: './src/gen',
clean
: true },
plugins
: [
pluginTs
()],
})

TypeScript + React Query ​

Generates types and TanStack Query hooks for React.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
import {
pluginAxios
} from '@kubb/plugin-axios'
import {
pluginReactQuery
} from '@kubb/plugin-react-query'
export default
defineConfig
({
input
: './petStore.yaml',
output
: {
path
: './src/gen',
clean
: true },
plugins
: [
pluginTs
(),
pluginAxios
(),
pluginReactQuery
()],
})

TypeScript + Vue Query ​

Generates types and TanStack Query hooks for Vue.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
import {
pluginVueQuery
} from '@kubb/plugin-vue-query'
export default
defineConfig
({
input
: './petStore.yaml',
output
: {
path
: './src/gen',
clean
: true },
plugins
: [
pluginTs
(),
pluginVueQuery
()],
})

Zod schemas + MSW handlers ​

Runtime validation with Zod, plus MSW request handlers backed by Faker.js mock data.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
import {
pluginZod
} from '@kubb/plugin-zod'
import {
pluginFaker
} from '@kubb/plugin-faker'
import {
pluginMsw
} from '@kubb/plugin-msw'
export default
defineConfig
({
input
: './petStore.yaml',
output
: {
path
: './src/gen',
clean
: true },
plugins
: [
pluginTs
(),
pluginZod
(),
pluginFaker
(),
pluginMsw
()],
})

Faker + Zod for testing ​

Generates Faker.js data factories next to Zod schemas. Use them in unit and integration tests.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
import {
pluginZod
} from '@kubb/plugin-zod'
import {
pluginFaker
} from '@kubb/plugin-faker'
export default
defineConfig
({
input
: './petStore.yaml',
output
: {
path
: './src/gen',
clean
: true },
plugins
: [
pluginTs
(),
pluginZod
(),
pluginFaker
()],
})

Pick the HTTP client ​

Choose Fetch or Axios by registering the matching plugin. Swap pluginFetch for pluginAxios to use the global fetch instead.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
import {
pluginAxios
} from '@kubb/plugin-axios'
export default
defineConfig
({
input
: './petStore.yaml',
output
: {
path
: './src/gen',
clean
: true },
plugins
: [
pluginTs
(),
pluginAxios
()],
})

Multiple specifications ​

Generate from several specs in one run. Pass an array to defineConfig. Each entry runs on its own, with its own plugins and output directory.

Set a name per entry so each one shows up in the CLI output.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
export default
defineConfig
([
{
name
: 'petStore',
input
: './petStore.yaml',
output
: {
path
: './src/gen/petStore',
clean
: true },
plugins
: [
pluginTs
()],
}, {
name
: 'userApi',
input
: './userApi.yaml',
output
: {
path
: './src/gen/userApi',
clean
: true },
plugins
: [
pluginTs
()],
}, ])

Conditional config (watch-aware) ​

Pass a function to defineConfig to read CLI context. Here it turns off clean in watch mode so incremental runs stay fast.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
export default
defineConfig
(({
watch
}) => ({
input
: './petStore.yaml',
output
: {
path
: './src/gen',
clean
: !
watch
,
},
plugins
: [
pluginTs
()],
}))

Run kubb generate --watch to regenerate on spec changes.

Format with Biome, lint with Oxlint ​

Format generated files with Biome and lint them with Oxlint on every build. Set format and lint to 'auto' to pick whichever tool is installed.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
export default
defineConfig
({
input
: './petStore.yaml',
output
: {
path
: './src/gen',
clean
: true,
format
: 'biome',
lint
: 'oxlint',
},
plugins
: [
pluginTs
()],
})

Run a command after generation ​

Use output.postGenerate to run shell commands, such as a formatter pass or a type check, once the generated files are formatted and linted.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
export default
defineConfig
({
input
: './petStore.yaml',
output
: {
path
: './src/gen',
postGenerate
: ['biome check --write ./src/gen'],
},
plugins
: [
pluginTs
()],
})

Monorepo with multiple outputs ​

Generate a different client library per package or team from one config file.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
import {
pluginAxios
} from '@kubb/plugin-axios'
import {
pluginReactQuery
} from '@kubb/plugin-react-query'
export default
defineConfig
([
{
name
: 'public-api',
input
: './specs/public.yaml',
output
: {
path
: './packages/public-api/src/gen' },
plugins
: [
pluginTs
(),
pluginAxios
(),
pluginReactQuery
()],
}, {
name
: 'admin-api',
input
: './specs/admin.yaml',
output
: {
path
: './packages/admin-api/src/gen' },
plugins
: [
pluginTs
(),
pluginAxios
()],
}, ])

Environment-aware configuration ​

Pick input and output from NODE_ENV so one config covers development, staging, and production.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
import {
pluginAxios
} from '@kubb/plugin-axios'
const
env
=
process
.
env
['NODE_ENV'] ?? 'development'
const
envConfig
= {
development
: {
input
: 'http://localhost:3000/openapi.json',
output
: {
path
: './src/gen',
clean
: true },
},
staging
: {
input
: 'https://staging-api.example.com/openapi.json',
output
: {
path
: './src/gen',
clean
: true },
},
production
: {
input
: './specs/production.json',
output
: {
path
: './src/gen',
clean
: true },
}, } as
const
export default
defineConfig
({
...
envConfig
[
env
as keyof typeof
envConfig
],
plugins
: [
pluginTs
(),
pluginAxios
()],
})

Programmatic build ​

Drive Kubb from a script with createKubb from the kubb package, paired with Diagnostics from kubb/kit. This fits monorepo orchestration and custom build pipelines. It applies the same defaults as defineConfig, so a shared config generates the same files through the CLI and a script.

generate.ts
typescript
import { 
createKubb
} from 'kubb'
import {
Diagnostics
} from 'kubb/kit'
import {
pluginTs
} from '@kubb/plugin-ts'
const
kubb
=
createKubb
({
input
: './petStore.yaml',
output
: {
path
: './gen' },
plugins
: [
pluginTs
()],
})
kubb
.
hooks
.
hook
('kubb:plugin:end', ({
plugin
,
duration
}) => {
console
.
log
(`${
plugin
.
name
} completed in ${
duration
}ms`)
}) const {
files
,
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)
}
console
.
log
(`Generated ${
files
.
length
} files`)

Use .build() instead of .safeBuild() if you want it to throw on errors rather than return diagnostics. See the Kit API for the full Kubb instance API.

CI validation ​

Validate the OpenAPI spec and fail the build on errors. Use output.postGenerate to run kubb validate after generation.

kubb.config.ts
typescript
import { 
defineConfig
} from 'kubb/config'
import {
pluginTs
} from '@kubb/plugin-ts'
export default
defineConfig
({
input
: './petStore.yaml',
output
: {
path
: './src/gen',
clean
: true,
postGenerate
: ['kubb validate ./petStore.yaml'] },
plugins
: [
pluginTs
()],
})