Beta You're reading the docs for Kubb v5, which is currently in beta. View the stable v4 docs
Skip to content

Basic Usage

In this tutorial you start from an empty config and finish with generated types, a client, and hooks imported into your app. Work through the five steps in order. 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.

kubb.config.ts
typescript
import {  } from 'kubb'

export default ({
  : { : './petStore.yaml' },
  : { : './src/gen', : true },
})

A couple of details to note here. input.path accepts a local file path or a URL, so you can point it at a spec on disk or one served over HTTP. output.clean: true wipes the output directory before each run, which keeps stale files from piling 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.

typescript
import {  } from 'kubb'
import {  } from '@kubb/plugin-ts'

export default ({
  : { : './petStore.yaml' },
  : { : './src/gen', : true },
  : [({ : { : 'models' } })],
})
typescript
import {  } from 'kubb'
import {  } from '@kubb/plugin-ts'
import {  } from '@kubb/plugin-axios'

export default ({
  : { : './petStore.yaml' },
  : { : './src/gen', : true },
  : [({ : { : 'models' } }), ({ : { : 'clients' } })],
})
typescript
import {  } from 'kubb'
import {  } from '@kubb/plugin-ts'
import {  } from '@kubb/plugin-axios'
import {  } from '@kubb/plugin-react-query'

export default ({
  : { : './petStore.yaml' },
  : { : './src/gen', : true },
  : [({ : { : 'models' } }), ({ : { : 'clients' } }), ({ : { : 'hooks' } })],
})
typescript
import {  } from 'kubb'
import {  } from '@kubb/plugin-ts'
import {  } from '@kubb/plugin-axios'
import {  } from '@kubb/plugin-react-query'
import {  } from '@kubb/plugin-zod'
import {  } from '@kubb/plugin-msw'

export default ({
  : { : './petStore.yaml' },
  : { : './src/gen', : true },
  : [
    ({ : { : 'models' } }),
    ({ : { : 'clients' } }),
    ({ : { : 'hooks' } }),
    ({ : { : 'schemas' } }),
    ({ : { : 'mocks' } }),
  ],
})

Here is what each plugin in those examples gives you.

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

With the config saved, run the generate command. You should see each plugin report in turn and a summary at the end.

Terminal
shell
command: kubb generate
output:
  -  Generation started
  -  @kubb/plugin-ts          completed in 98ms
  -  @kubb/plugin-axios       completed in 77ms
  -  @kubb/plugin-react-query completed in 201ms
  -  @kubb/plugin-zod         completed in 134ms
  -  @kubb/plugin-msw         completed in 63ms
  -  Generation completed
  -
  -  Plugins  5 passed (5)
  -    Files  156 generated
  - Duration  1.2s
  -   Output  ./src/gen

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

Now for the payoff. 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.

typescript
import type {  } from './gen/models/Pet'

const :  = { : 1, : 'Cat' }
typescript
import { getPetById } from './gen/clients/getPetById'

const { data: pet } = await getPetById({ path: { petId: 1 } })
typescript
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>
}
typescript
import { petSchema } from './gen/schemas/petSchema'

const result = petSchema.safeParse(unknown)
typescript
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.