Skip to content

Migrating to Kubb v3

New Features

Generators

TIP

Generators are a replacements of templates

See Generators.

kubb.config.ts

2 extra options have been added to the output:

output.extension

In the latest Node.js version, file extensions are required, so we automatically add .ts to every file. However, not all projects use the latest Node.js configuration for extensions. With this option, you can remove the extension or use .js instead.

See output.extension.

output.barrelType

Specify how index.ts files should be created, this will work for the root index.ts file. On plugin level there is also a new option to define this.

See output.barrelType.

Rewrite of the CLI

Left: v3Right: v2

React-DevTools The CLI and core have been revamped for improved speed and in v3 it will also display more relevant information.

  • Progressbar for the execution of plugins.
  • Progressbar for the writing of files.
  • Timestamps next to every command that is being executed.
  • Better support for CI tools
  • Use of TypeScript Strict
  • 20-30% faster overall execution
  • Debug mode(--debug) that will create 2 log files
    • .kubb/kubb-DATE_STRING.log
    • .kubb/kubb-files.log
  • All issues can be seen here: Kubb v3 ideas

Breaking Changes

Plugin renames

We previously used the name swagger to indicate that we only supported Swagger files. However, we now also support OpenAPI v3 and v3.1. This change allows for the potential integration of additional specifications beyond just OpenAPI files in the future.

TIP

Default imports are also being removed in v3 so you need to import a plugin as follow(support for better treeshaking for ESM):

import { pluginReactQuery } from '@kubb/plugin-react-query'

  • @kubb/swagger-client becomes @kubb/plugin-client
  • @kubb/swagger-faker becomes @kubb/plugin-faker
  • @kubb/swagger-msw becomes @kubb/plugin-msw
  • @kubb/swagger becomes @kubb/plugin-oas
  • @kubb/plugin-tanstack-query becomes @kubb/plugin-react-query for React
  • @kubb/plugin-tanstack-query becomes @kubb/plugin-solid-query for Solid
  • @kubb/plugin-tanstack-query becomes @kubb/plugin-svelte-query for Svelte
  • @kubb/plugin-tanstack-query becomes @kubb/plugin-react-query for Vue
  • @kubb/swagger-redoc becomes @kubb/plugin-redoc
  • @kubb/swagger-swr becomes @kubb/plugin-swr
  • @kubb/swagger-ts becomes @kubb/plugin-ts
  • @kubb/swagger-zod becomes @kubb/plugin-zod
  • @kubb/swagger-zodios becomes @kubb/plugin-zodios

Tanstack-query

We will discontinue support for (Tanstack-Query](https://tanstack.com/query/latest/docs/framework/react/overview) v4 in favor of v5. If you still require generation for v4, you can use Kubb v2. Additionally, each framework will now be packaged separately instead of being included in a single package that contains code for all frameworks.

FrameworkPackages
'react''@kubb/plugin-react-query'
'solid''@kubb/plugin-solid-query'
'svelte''@kubb/plugin-svelte-query'
'vue''@kubb/plugin-vue-query'
kubb.config.ts
typescript
import { defineConfig } from '@kubb/core'
import { pluginOas } from '@kubb/plugin-oas'
import { pluginTanstackQuery } from '@kubb/swagger-tanstack-query'
import { pluginReactQuery } from '@kubb/plugin-react-query'
import { pluginTs } from '@kubb/plugin-ts'

export default defineConfig({
  input: {
    path: './petStore.yaml',
  },
  output: {
    path: './src/gen',
  },
  plugins: [
    pluginOas(),
    pluginTs(),
    pluginTanstackQuery({
      output: {
        path: './hooks',
      },
      framework: 'react',
    }),
    pluginReactQuery({
      output: {
        path: './hooks',
      },
    }),
  ],
})

MSW

We will discontinue support for (MSW](https://mswjs.io/) v1 in favour of using v2. If you still need to generate mocks for v1, you could use Kubb v2.

Output

  • output.banner: Add some code in the beginning of every file
  • output.footer: Add some code in the end of every file
  • output.exportType: Behaviour stayed the same, we renamed the option to output.barrelType and simplified the values.
kubb.config.ts
typescript
import { defineConfig } from "@kubb/core"
import { pluginOas } from "@kubb/plugin-oas"
import { pluginTs } from "@kubb/plugin-ts"
import { pluginClient } from '@kubb/plugin-client'

export default defineConfig({
  root: '.',
  input: {
    path: './petStore.yaml',
  },
  output: {
    path: './src/gen',
  },
  plugins: [
    pluginOas(),
    pluginClient({
      output: {
        exportType: false,
        barrelType: false,
      },
    }),
    pluginClient({
      output: {
        exportType: 'barrel',
        barrelType: 'all',
      },
    }),
    pluginClient({
      output: {
        exportType: 'barrelNamed',
        barrelType: 'named',
      },
    }),
  ],
})
  • output.extName: Rather than defining this in every plugin, we chose to move it to output.extension.
kubb.config.ts
typescript
import { defineConfig } from "@kubb/core"
import { pluginOas } from "@kubb/plugin-oas"
import { pluginTs } from "@kubb/plugin-ts"
import { pluginClient } from '@kubb/plugin-client'

export default defineConfig({
  root: '.',
  input: {
    path: './petStore.yaml',
  },
  output: {
    path: './src/gen',
    extension: {
      '.ts': '.js',
    },
  },
  plugins: [
    pluginOas(),
    pluginClient({
      output: {
        path: './clients/axios',
        extName: '.js',
      },
    }),
  ],
})
  • output.exportAs: This property was only usable for @kubb/plugin-client where we aimed to consolidate the functionality into one single controller. In v3, using group will already create the controller file.
typescript
import { defineConfig } from "@kubb/core"
import { pluginOas } from "@kubb/plugin-oas"
import { pluginTs } from "@kubb/plugin-ts"
import { pluginClient } from '@kubb/plugin-client'

export default defineConfig({
  root: '.',
  input: {
    path: './petStore.yaml',
  },
  output: {
    path: './src/gen',
  },
  plugins: [
    pluginOas(),
    pluginClient({
      output: {
        path: './clients/axios',
        exportAs: 'clients'
      },
      group: {
        type: 'tag',
        name({ group }){
          return `${group}Controller`
        }
      }
    }),
  ],
})
typescript
import { addPet } from './addPet.js'
import { deletePet } from './deletePet.js'

export function petService() {
  return { addPet, deletePet }
}

Group

  • group.output: Removed in favour of using group.name, the output will automatically be created based on the root, output.path and output.path of the selected plugin.
kubb.config.ts
typescript
import { defineConfig } from "@kubb/core"
import { pluginOas } from "@kubb/plugin-oas"
import { pluginTs } from "@kubb/plugin-ts"
import { pluginClient } from '@kubb/plugin-client'

export default defineConfig({
  root: '.',
  input: {
    path: './petStore.yaml',
  },
  output: {
    path: './src/gen',
  },
  plugins: [
    pluginOas(),
    pluginClient({
      group: {
        type: 'tag',
        output: './clients/axios/{{tag}}Service',
        name: ({ group }) => `${group}Service`,
      },
    }),
  ],
})
  • group.exportAs: This property was only usable for @kubb/plugin-client where we aimed to consolidate the functionality into one single controller. In v3, using group will already create the controller file.
typescript
import { defineConfig } from "@kubb/core"
import { pluginOas } from "@kubb/plugin-oas"
import { pluginTs } from "@kubb/plugin-ts"
import { pluginClient } from '@kubb/plugin-client'

export default defineConfig({
  root: '.',
  input: {
    path: './petStore.yaml',
  },
  output: {
    path: './src/gen',
  },
  plugins: [
    pluginOas(),
    pluginClient({
      output: {
        path: './clients/axios',
      },
      group: {
        exportAs: 'clients',
        name({ group }){
          return `${group}Controller`
        }
      }
    }),
  ],
})
typescript
import { addPet } from './addPet.js'
import { deletePet } from './deletePet.js'

export function petService() {
  return { addPet, deletePet }
}

More

  • Minimal support of Node 20
  • Refactor of grouping(use of name instead of output) and output based on output of the current plugin
  • Removal of the Zodios plugin

Plugin Specific changes

@kubb/plugin-oas

We used openapi-format before to already filter out some Operations or Paths but in v3 this has been removed in favour of using https://github.com/thim81/openapi-format before using your Swagger/OpenAPI in Kubb.

  • experimentalFilter
  • experimentalSort

See Filter And Sort.

@kubb/plugin-client

  • client.importPath becomes importPath
  • operations will control the creation of a file with all operations grouped by methods.
  • parser will make it possible to chose between using no parser(client) or using Zod(zod).
  • paramsType will make it possible to have one object to pass your pathParams, params, headers and data.

@kubb/plugin-ts

  • enumType 'asPascalConst' has been removed as an option.
  • enumSuffix will be 'enum' by default.
  • mapper can be used to override which TypeScript TsNode that should be used.

@kubb/plugin-zod

  • typedSchema becomes inferred
  • operations will control the creation of a file with all operations grouped by methods.
  • mapper can be used to override which Zod primitives that should be used.

@kubb/plugin-faker

  • mapper can be used to override which Faker functionality that should be used.

@kubb/plugin-swr

  • dataReturnType becomes client.dataReturnType
  • pathParamsType same as in @kubb/plugin-client
  • parser same as in @kubb/plugin-client
  • queryKey same as in @kubb/plugin-react-query
  • query.methods same as in @kubb/plugin-react-query
  • query.importPath same as in @kubb/plugin-react-query
  • mutationKey same as in @kubb/plugin-react-query
  • mutation.methods same as in @kubb/plugin-react-query
  • mutation.importPath same as in @kubb/plugin-react-query
  • paramsType will make it possible to have one object to pass your pathParams, params, headers and data.

@kubb/plugin-react-query

  • dataReturnType becomes client.dataReturnType
  • pathParamsType same as in @kubb/plugin-client
  • parser same as in @kubb/plugin-client
  • queryOptions has been removed as an option
  • mutate.methods becomes mutation.methods
  • mutate.importPath becomes mutation.importPath
  • Mutations will include a generated mutationkey
  • enabled will be generated based on which params are required
  • Support for signal, this makes it possible to cancel a request
  • Removal of mutate.variablesType and use 'mutate' as default
  • paramsType will make it possible to have one object to pass your pathParams, params, headers and data.

@kubb/plugin-msw

  • parser to switch between using Faker('faker') for your data or define your own data with 'data'.
  • By default, use of a function with data as parameter to override the response of MSW.
typescript
export const addPetHandler = http.post('*/pet', function handler(info) {
  return new Response(JSON.stringify(createAddPetMutationResponse()), {
    headers: {
      'Content-Type': 'application/json',
    },
  }) 
}) 

export function addPetHandler(data?: AddPetMutationResponse) {
  return http.post('*/pet', function handler(info) {
    return new Response(JSON.stringify(createAddPetMutationResponse(data)), {
      headers: {
        'Content-Type': 'application/json',
      },
    }) 
  }) 
}

Released under the MIT License.