Basic Usage
Start from an empty config and end with generated types, a client, and hooks imported into your app. Follow the five steps in order, and by the end you will have run Kubb once and seen real code land in ./src/gen.
1. Create the config
Everything Kubb does starts from kubb.config.ts. Begin with a minimal config that points at your spec and names an output directory.
import { defineConfig } from 'kubb/config'
export default defineConfig({
input: './petStore.yaml',
output: { path: './src/gen', clean: true },
})input accepts a file path, URL, inline spec, or parsed object, and output.clean: true wipes the output directory before each run so stale files don't pile up.
2. Pick your plugins
Each output format is its own plugin, so you only generate what you ask for. Start small and add plugins as you need them. The tabs below build up from types alone to a full setup with types, a client, hooks, schemas, and mocks.
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({ output: { path: 'models' } })],
})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({ output: { path: 'models' } }), pluginAxios({ output: { path: 'clients' } })],
})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({ output: { path: 'models' } }), pluginAxios({ output: { path: 'clients' } }), pluginReactQuery({ output: { path: 'hooks' } })],
})import { defineConfig } from 'kubb/config'
import { pluginTs } from '@kubb/plugin-ts'
import { pluginAxios } from '@kubb/plugin-axios'
import { pluginReactQuery } from '@kubb/plugin-react-query'
import { pluginZod } from '@kubb/plugin-zod'
import { pluginMsw } from '@kubb/plugin-msw'
export default defineConfig({
input: './petStore.yaml',
output: { path: './src/gen', clean: true },
plugins: [
pluginTs({ output: { path: 'models' } }),
pluginAxios({ output: { path: 'clients' } }),
pluginReactQuery({ output: { path: 'hooks' } }),
pluginZod({ output: { path: 'schemas' } }),
pluginMsw({ output: { path: 'mocks' } }),
],
})| Plugin | Package | Generates |
|---|---|---|
pluginTs | @kubb/plugin-ts | TypeScript types and interfaces |
pluginAxios | @kubb/plugin-axios | Axios-based HTTP client functions |
pluginReactQuery | @kubb/plugin-react-query | TanStack Query hooks |
pluginZod | @kubb/plugin-zod | Zod validation schemas |
pluginMsw | @kubb/plugin-msw | MSW request handlers |
NOTE
pluginAxios, pluginReactQuery, and pluginMsw each require pluginTs in the same config. pluginReactQuery also calls a registered client plugin, so add pluginAxios or pluginFetch alongside it.
See the plugins catalogue for the full list.
3. Run generate
Run the generate command. Each plugin reports in turn, followed by a summary.
Kubb creates one folder per plugin under output.path, so the layout mirrors the config you wrote. Re-run it after every spec change. See kubb generate for flags like --watch and --reporter.
4. Use the generated code
Import the generated code into your app. The import paths follow the output.path values you set for each plugin, so a plugin pointed at models lives under gen/models.
// @filename: src/gen/models/Pet.ts
export type Pet = { id: number; name: string }
// @filename: src/app.ts
// ---cut---
import type { Pet } from './gen/models/Pet'
const pet: Pet = { id: 1, name: 'Cat' }import { getPetById } from './gen/clients/getPetById'
const { data: pet } = await getPetById({ path: { petId: 1 } })import { useGetPetById } from './gen/hooks/useGetPetById'
function Pet({ id }: { id: number }) {
const { data, isLoading } = useGetPetById({ path: { petId: id } })
if (isLoading) return null
return <span>{data?.name}</span>
}import { petSchema } from './gen/schemas/petSchema'
const result = petSchema.safeParse(unknown)import { setupServer } from 'msw/node'
import { getPetByIdHandler } from './gen/mocks/getPetByIdHandler'
const server = setupServer(getPetByIdHandler())
server.listen()5. Keep it in sync
That is the full loop. From now on, run npm run generate whenever the spec changes, then commit the output. To skip the manual step, unplugin-kubb generates during your build with Vite, Rollup, Webpack, and others.