Skip to content

Templates tutorial ​

This tutorial will describe how you can setup Kubb and use our Swagger-client plugin to generate a client based on Swagger/OpenAPI file. More info about how templates are working behind the scenes can be found here.


The setup will contain from the beginning the following folder structure:
.
├── src
├── petStore.yaml
├── kubb.config.ts
└── package.json
typescript
import { Client, Operations } from '@kubb/swagger-client/components'

type Templates = {
  operations: typeof Operations.templates
  client: typeof Client.templates
}
export type Options = {
  // ....
  /**
   * Make it possible to override one of the templates
   */
  templates?: Partial<Templates>
}

Step one ​

Create a React component that will be used to override the default behavior of the generated client(@kubb/swagger-client).
In this React component we want to return a function export function addPet() that will call Axios. To do that we add a Function component and as children we provide the following snippet:

typescript
 {`return axios.${client.method}(${clientParams}`}

We also want to import axios, to do that we can use File.Import. Next to that we will also make it async, provide some JSDoc properties and define a name for the generated function.

tsx
import React from 'react'

import { File, Function } from '@kubb/react'
import { Client } from '@kubb/swagger-client/components'

function ClientTemplate({ name, generics, returnType, params, JSDoc, client }: React.ComponentProps<typeof Client.templates.default>) {
  const clientParams = [client.path.template, client.withData ? 'data' : undefined, 'options'].filter(Boolean).join(', ')

  return (
    <>
      <File.Import name="axios" path="axios" />
      <Function name={name} async export generics={generics} returnType={returnType} params={params} JSDoc={JSDoc}>
        {`return axios.${client.method}(${clientParams}`}
      </Function>
    </>
  )
}

Step two ​

Update your kubb.config.ts file to include the custom template.

TIP

If you want to use another language than JavaScript/TypeScript, override the root template with your own. See examples/python for an example on how you can do that.

tsx
import React from 'react'

import { File, Function } from '@kubb/react'
import { Client } from '@kubb/swagger-client/components'
import { defineConfig } from '@kubb/core'
import { pluginOas } from '@kubb/plugin-oas'
import { pluginClient } from '@kubb/swagger-client'

function ClientTemplate({ name, generics, returnType, params, JSDoc, client }: React.ComponentProps<typeof Client.templates.default>) {
  const clientParams = [client.path.template, client.withData ? 'data' : undefined, 'options'].filter(Boolean).join(', ')

  return (
    <>
      <File.Import name="axios" path="axios" />
      <Function name={name} async export generics={generics} returnType={returnType} params={params} JSDoc={JSDoc}>
        {`return axios.${client.method}(${clientParams}`}
      </Function>
    </>
  )
}

const templates = {
  client: {
    default: ClientTemplate,
    root: Client.templates.root
  },
} as const

export default defineConfig(() => {
  return {
    root: '.',
    input: {
      path: './petStore.yaml',
    },
    output: {
      path: './src',
    },
    plugins: [
      pluginOas(
        {
          output: false,
          validate: true,
        },
      ),
      pluginClient(
        {
          output: {
            path: 'models',
          },
          templates: {
            client: templates.client,
            operations: false,
          },
        },
      ),
    ],
  }
})

Step three ​

Run the Kubb script with the following command.

shell
bun run generate
shell
pnpm run generate
shell
npm run generate
shell
yarn run generate

Step four ​

The end result of a generated client based on the custom template.

TIP

See examples/react-query-v5 or examples/python for are more in depth example.

typescript
import client from '@kubb/swagger-client/client'
import axios from 'axios'
import type { ResponseConfig } from '@kubb/swagger-client/client'
import type { AddPetMutationRequest, AddPetMutationResponse } from '../../../models/ts/petController/AddPet'

/**
 * @description Add a new pet to the store
 * @summary Add a new pet to the store
 * @link /pet */
export async function addPet(
  data: AddPetMutationRequest,
  options: Partial<Parameters<typeof client>[0]> = {},
): Promise<ResponseConfig<AddPetMutationResponse>['data']> {
  return axios.post(`/pet`, data, options)
}

Released under the MIT License.