Skip to content

Changelog

4.37.2

🐛 Bug Fixes

@kubb/plugin-mcp

  • #2996 8aeecf3 Thanks @copilot-swe-agent! - Fixed an issue where inputSchema was generating z.string() instead of z.enum([...]) for path parameters with an enum constraint in the OpenAPI specification.

    Before:

    typescript
    const inputSchema = z.object({
      status: z.string(), // Incorrect
    });

    After:

    typescript
    const inputSchema = z.object({
      status: z.enum(['active', 'inactive']), // Correct
    });

4.37.1

🐛 Bug Fixes

@kubb/plugin-client

  • #2951 926e3d7 Thanks @copilot-swe-agent! - Fixed an issue causing unused variable declarations when paramsCasing was set with urlType: 'export'.

    Issue: A const variable for mapping path parameters containing underscores (e.g., item_id) to camelcase (e.g., itemId) was emitted unnecessarily, resulting in TypeScript noUnusedLocals errors.

    Fix: The mapping variable is now only emitted when the URL is built inline (i.e., when no exported URL function is used). This eliminates the unused variable error for exported URL functions.

    Before:

    typescript
    function getItem(itemId: string) {
      const item_id = itemId; // unused variable
      return fetch(`/api/v1/items/${item_id}`);
    }

    After:

    typescript
    function getItem(itemId: string) {
      return fetch(`/api/v1/items/${itemId}`);
    }

4.37.0

✨ Features

@kubb/plugin-ts

  • #2916 117fe78 Thanks @julian99m! - New config param enumTypeSuffix to specify a custom type name suffix when using enumType: asConst|asPascalConst. Default value Key for backwards compatibility.

    Before/Default:

    typescript
    export const GetPetsQueryParamsStatusEnum = { ... }
    export type GetPetsQueryParamsStatusEnumKey = ...

    After:

    typescript
    export const GetPetsQueryParamsStatusEnum = { ... }
    export type GetPetsQueryParamsStatusEnumCustomSuffix = ... // enumTypeSuffix=CustomSuffix

    This change restores compatibility with the behavior before PR #2467 as well as maintaining the default behavior after said PR.

4.36.5

✨ Features

@kubb/cli @kubb/mcp

  • Support kubb.config.mts and kubb.config.cts config file extensions. Users migrating to "moduleResolution": "bundler" (e.g. TypeScript 6) can now use .mts or .cts extensions for their Kubb config file.

4.36.2

📦 Dependencies

  • Upgrade external packages

4.36.1

✨ Features

@kubb/core

  • a4ac8d2 Thanks @stijnvanhulle! - Exposed a new URLPath helper to simplify the management and manipulation of URL paths in custom plugins.

    The URLPath helper provides utility methods for standardizing and assembling paths, making it easier to ensure consistency in generated URLs across various plugins.

    typescript
    import { URLPath } from "@kubb/core";
    
    const path = new URLPath("api/v1");
    path.append("users");
    path.replace("v1", "v2");
    console.log(path.toString()); // Outputs "api/v2/users"

4.36.0

✨ Features

@kubb/core

  • #2759 4e06911 Thanks @stijnvanhulle! - Add storage abstraction for generated output.

    Introduces a storage option in output that replaces direct filesystem writes with a pluggable storage layer, inspired by the Nitro/unstorage API.

    New exports from @kubb/core:

    • defineStorage(builder) — factory helper (same pattern as definePlugin/defineLogger/defineAdapter) that wraps a builder function and makes options optional.
    • fsStorage() — built-in filesystem driver; the default when no storage is configured, preserving existing on-disk behavior.
    • memoryStorage() — built-in in-memory driver; useful for testing and dry-run scenarios.
    • DefineStorage — TypeScript interface for implementing custom drivers.

    output.write is now deprecated. Setting write: false for dry-runs still works and continues to be supported.

    typescript
    import { defineConfig, defineStorage, fsStorage } from "@kubb/core";
    
    // Default (no change needed for existing configs)
    export default defineConfig({
      output: { path: "./src/gen" },
    });
    
    // Explicit filesystem storage
    export default defineConfig({
      output: { path: "./src/gen", storage: fsStorage() },
    });
    
    // Custom in-memory storage
    export const memoryStorage = defineStorage((_options) => {
      const store = new Map<string, string>();
      return {
        name: "memory",
        async hasItem(key) {
          return store.has(key);
        },
        async getItem(key) {
          return store.get(key) ?? null;
        },
        async setItem(key, value) {
          store.set(key, value);
        },
        async removeItem(key) {
          store.delete(key);
        },
        async getKeys() {
          return [...store.keys()];
        },
        async clear() {
          store.clear();
        },
      };
    });

4.35.1

🐛 Bug Fixes

@kubb/plugin-ts

  • #2754 e24fe13 Thanks @copilot-swe-agent! - Fix crash when generating enums with negative numeric values (e.g., enum: [-1, 0, 5]). Negative numbers now correctly use createPrefixUnaryExpression instead of createNumericLiteral for all enum type variants (literal, inlineLiteral, enum, constEnum).
typescript
// Invalid code for negative numbers was generated
export const MyEnum = {
  Negative: -1,
  Zero: 0,
  Positive: 5,
}
typescript
// Negative numbers now properly use createPrefixUnaryExpression
export const MyEnum = {
  Negative: -1,
  Zero: 0,
  Positive: 5,
}

4.35.0

✨ Features

@kubb/plugin-client

  • #2554 4d8616c Thanks @icholy! - Add wrapper option to generate a wrapper class that composes all tag-based client classes into a single entry point.
typescript

const api = new ApiWrapper({
  client: new HttpClient(),
});
const user = await api.user.getUserById({ id: '123' });

4.34.0

✨ Features

@kubb/ast

  • 6223e05 Thanks @stijnvanhulle! - Add RootMeta type to RootNode with optional meta field for format-agnostic API document metadata (title, version, baseURL). Convert all node interface declarations to type aliases for consistency.

4.33.5

🐛 Bug Fixes

@kubb/oas & @kubb/plugin-oas

  • #2738 45b7dc7 Thanks @stijnvanhulle! - Fix $ref resolution in Oas.getSchemas() to prevent self-referential z.lazy() output when the bundler deduplicates schemas referenced from multiple external files. The resolution logic is moved from SchemaGenerator into Oas where it belongs.

4.33.4

🐛 Bug Fixes

@kubb/core

  • Improved internal package management to ensure better stability and consistency across plugins. This change resolves a range of minor bugs caused by dependency mismatches.

4.33.3

🐛 Bug Fixes

@kubb/oas

  • Fixed $ref parameter handling in getParametersSchema() to resolve $ref parameters directly following changes in oas v31. This adjustment ensures all parameters, including those filtered out in getParameters(), are now accounted for as part of schema generation.
typescript
export const parametersSchema = getParameters({
  ...otherParameters,
  $refParams: undefined, // Missing $ref parameters
});
typescript
export const parametersSchema = resolveParameters({
  ...otherParameters,
  resolvedRefs: $refParams, // Ensures $ref parameters are included
});

4.33.2

🐛 Bug Fixes

@kubb/plugin-oas, @kubb/plugin-zod

Fixed $ref schemas with a sibling default value not generating .default() in Zod output.

When an OpenAPI query parameter uses a $ref alongside a default value (e.g. {"$ref": "#/components/schemas/ProjectType", "default": "project"}), the generated Zod schema now correctly includes the .default() modifier.

typescript
export const projectsGetQueryParamsSchema = z.object({
  get type() {
    return projectTypeSchema  // missing .default()
  },
})
typescript
export const projectsGetQueryParamsSchema = z.object({
  get type() {
    return projectTypeSchema.default('project')
  },
})

4.33.1

🚀 Breaking Changes

@kubb/core, @kubb/cli, @kubb/plugin-oas

Extracted node-native and pure-TypeScript utilities into the new private package @internals/utils. These utilities are now bundled into each consuming package at build time. Affected utilities include:

  • @kubb/core:
    • FS utilities: clean, exists/existsSync, read/readSync, write, getRelativePath
    • Time utils: formatHrtime, formatMs, getElapsedMs
    • System-related: canUseTTY, isCIEnvironment, isGitHubActions, serializePluginOptions
  • @kubb/cli:
    • CLI formatting and error utilities: randomCliColor, randomColors, formatMsWithColor, toError, getErrorMessage
  • @kubb/plugin-oas: resolveServerUrl (moved directly into @kubb/oas due to OAS-specific dependencies)

The @kubb/core/fs and @kubb/core/utils subpath exports have been removed. Symbols previously accessible from these subpaths are now exported via the top-level entry point of @kubb/core.

Migration:

Update imports referencing @kubb/core/fs or @kubb/core/utils to use:

typescript
import { clean, getRelativePath } from '@kubb/core';

✨ Features

@kubb/cli

  • Improved internal logic by bundling node-native utilities into a scoped internal package, reducing module redundancy and increasing maintainability. (#2689 by @stijnvanhulle)

4.33.0

✨ Features

@kubb/cli

Replaced citty with a zero-dependency CLI layer built on node:util's parseArgs. This new implementation makes command runners lazily importable, meaning the heavy runner logic is only loaded when a specific command is executed. Introduced defineCommand with typed option inference, a nodeAdapter, and a createCLI factory for creating custom CLI tools. (#2675 by @stijnvanhulle)

4.32.4

🐛 Bug Fixes

@kubb/plugin-zod

Prevents typed: true Zod generation from emitting duplicate ToZod imports in generated files. Previously, specifying typed: true could result in redundant ToZod imports, causing unnecessary clutter and potential conflicts in the generated code.

Example:

typescript
import { z } from 'zod';
import { ToZod } from 'kubb-plugin-zod';
import { ToZod } from 'kubb-plugin-zod'; // Duplicate import

const schema = z.object({...});
typescript
import { z } from 'zod';
import { ToZod } from 'kubb-plugin-zod';

const schema = z.object({...});

4.32.3

🐛 Bug Fixes

@kubb/plugin-react-query, @kubb/plugin-vue-query, @kubb/plugin-svelte-query, @kubb/plugin-solid-query

Fix user-provided query options (e.g. enabled) not applied in generated hooks

The local destructured variable queryOptions in generated hook code was shadowing the imported queryOptions function from TanStack Query. This caused options like enabled: false passed at the call site to be silently ignored in certain environments.

The fix renames the local variable to resolvedOptions and ensures user options are spread before the explicit queryKey in the query call, so call-site overrides are always respected.

typescript
const { client: queryClient, ...queryOptions } = queryConfig  // shadows import!
const query = useQuery({
  ...getPetByIdQueryOptions(petId, config),
  queryKey,
  ...queryOptions,  // user options could be ignored
} as unknown as QueryObserverOptions, queryClient)
typescript
const { client: queryClient, ...resolvedOptions } = queryConfig  // no shadow
const query = useQuery({
  ...getPetByIdQueryOptions(petId, config),
  ...resolvedOptions,  // user options always applied
  queryKey,
} as unknown as QueryObserverOptions, queryClient)

4.32.3

🐛 Bug Fixes

@kubb/plugin-react-query, @kubb/plugin-vue-query, @kubb/plugin-svelte-query, @kubb/plugin-solid-query

Fix user-provided query options (e.g. enabled) not applied in generated hooks

Options passed via the query parameter to generated hooks (e.g. { query: { enabled: false } }) were being silently ignored. The local destructured variable queryOptions was shadowing the imported queryOptions function from TanStack Query, which could cause the user-supplied override to be lost.

The fix renames the local variable to resolvedOptions and ensures user options are spread before the explicit queryKey in the query call.

typescript
const { client: queryClient, ...queryOptions } = queryConfig  // shadows import!
const query = useQuery({
  ...getPetByIdQueryOptions(petId, config),
  queryKey,
  ...queryOptions,  // user options could be ignored
} as unknown as QueryObserverOptions, queryClient)
typescript
const { client: queryClient, ...resolvedOptions } = queryConfig  // no shadow
const query = useQuery({
  ...getPetByIdQueryOptions(petId, config),
  ...resolvedOptions,  // user options always applied
  queryKey,
} as unknown as QueryObserverOptions, queryClient)

4.32.2

🐛 Bug Fixes

@kubb/plugin-client

Fix invalid JavaScript variable names in path parameter const declarations

Path parameters with dashes (e.g., organization-id) previously produced invalid JavaScript, such as const organization-id = organizationId. These invalid declarations have been removed as the URL template already converts these parameters to camelCase, ensuring valid and error-free code.

typescript
// Invalid JavaScript output for path parameter
const organization-id = organizationId  // ❌ SyntaxError: Unexpected token '-'
typescript
// CamelCase is used directly for the path parameter
const organizationId = '12345'  // ✅ Correct and valid

Tests updated: Additional test cases verify path parameters with dashes produce valid JavaScript output.


@kubb/plugin-ts

Prevent barrel from exporting non-existent runtime consts for empty enum schemas

When enum schemas have no values (e.g., enum: [] or enum: [null]), the plugin previously attempted to export runtime constants, resulting in broken compilation. This has been fixed by generating a type Key = never alias when the enum is empty.

typescript
// Incorrect runtime constant export for empty enum
export const MyEnum = { } as const;  // ❌ Unused constant
typescript
// Correctly generates "type" alias for empty enum
export type MyEnumKey = never;  // ✅ No unused constant

Docs updated: Additional documentation for empty enum handling is available in the updated migration guide for plugin-ts.

@kubb/plugin-faker

Fix named array type aliases no longer wrapped in Partial<>

Named array type aliases are no longer erroneously wrapped with the Partial<> TypeScript utility type, ensuring the correct type generation.


📦 Dependencies

@kubb/fabric-core and @kubb/react-fabric

Updated to version 0.13.2, fixing the MaxListenersExceededWarning issue by dynamically adjusting process.maxListeners in onProcessExit(). The Fabric interface now exposes a new unmount() method to manage lifecycle events.

Fixes include:

  • Moving the createReactFabric() function to a broader scope in tests to prevent excessive event listener accumulation.
  • Added fabricChild.unmount() calls within the generation process to clean up residual listeners.

4.32.1

🐛 Bug Fixes

@kubb/plugin-client

Fix invalid JavaScript variable names in path parameter const declarations

Path parameters with dashes (e.g., organization-id) previously produced invalid JavaScript, such as const organization-id = organizationId. The URL template already converts these to camelCase, making the const declaration unnecessary. Parameters with invalid JavaScript identifiers are now filtered out to prevent errors.

typescript
// Invalid JavaScript output for path parameter
const organization-id = organizationId  // ❌ SyntaxError: Unexpected token '-'
typescript
// CamelCase is used directly for the path parameter
const organizationId = '12345'  // ✅ Correct and valid

Tests added: New test cases verify that path parameters with dashes produce valid JavaScript.


4.32.0

✨ Features

@kubb/plugin-oas

Added serverVariables option for resolving OpenAPI server URL template variables

When using serverIndex to select a server from the OpenAPI spec, URLs may contain template variables like {env} or {region}. The new serverVariables option lets you supply values for those variables at generation time. Variable values are validated against the enum list defined in the spec, and the spec-defined default is used as a fallback for any variable not explicitly provided.

typescript
import { defineConfig } from '@kubb/core'
import { pluginOas } from '@kubb/plugin-oas'

export default defineConfig({
  plugins: [
    pluginOas({
      serverIndex: 0,
      serverVariables: { env: 'prod' },
    }),
  ],
})
yaml
servers:
  - url: https://api.{env}.example.com
    variables:
      env:
        default: dev
        enum: [dev, staging, prod]
typescript
// baseURL resolves to: https://api.prod.example.com

4.31.6

🐛 Bug Fixes

@kubb/plugin-ts

Fix empty enum generating a broken barrel export

Two scenarios produce an enum with no runtime values:

  • enum: [null] — only null is valid; Kubb filters null out of the as const object, leaving an empty list.
  • enum: [] — a placeholder empty enum in the spec.

With enumType: 'asConst' or 'asPascalConst', createEnumDeclaration previously returned an empty VariableStatement even when there were no enum values. The barrel file emitted export { myConst } pointing to a const that was never written — breaking tsc and any bundler performing type-checking.

When enums.length === 0, createEnumDeclaration now returns [undefined, neverTypeAlias]. The undefined nameNode is skipped by the {nameNode && …} guard in Type.tsx, so no const is registered and the barrel omits the value export. The generated type becomes export type XKey = never, which is semantically correct for an empty enum.

typescript
// enum: [null] with enumType: 'asConst'
// barrel emitted a broken export pointing to a non-existent const
export { myConst }        // ❌ myConst was never written
export type MyConstKey = never
typescript
// barrel omits the value export entirely
export type MyConstKey = never  // ✅ self-contained, no dangling reference

@kubb/plugin-faker

Fix named array type aliases incorrectly wrapped in Partial<>

$ref schemas that resolve to a type with type: array were being wrapped in Partial<>, producing TypeScript errors like (Item | undefined)[] is not assignable to Item[]. Named array type aliases are no longer wrapped in Partial<>.

typescript
// $ref → { type: 'array', items: { $ref: '#/components/schemas/Item' } }
export function createItems(): Partial<Item>[] {
  return [createItem()]  // ❌ (Item | undefined)[] not assignable to Item[]
}
typescript
export function createItems(): Item[] {
  return [createItem()]  // ✅
}

@kubb/plugin-zod

Fix ToZod imported as a type import

ToZod was incorrectly emitted as import { ToZod }, causing type errors.

typescript
import { ToZod } from '@kubb/plugin-zod/zod'  // ❌ stripped at runtime
typescript
import type { ToZod } from '@kubb/plugin-zod/zod'  // ✅

4.31.5

🐛 Bug Fixes

@kubb/plugin-oas

Fix self-referential z.lazy() output for multi-file OpenAPI specs

When @readme/openapi-parser bundles multi-file specs, schemas in components.schemas could be represented as $ref objects. SchemaGenerator#doBuild now resolves those $ref entries before calling parse(), preventing output like export const parcelSchema = z.lazy(() => parcelSchema).

typescript
// multi-file spec: parcel.yaml referenced from main spec
// output was a self-referential lazy schema
export const parcelSchema = z.lazy(() => parcelSchema)
typescript
// multi-file spec: parcel.yaml referenced from main spec
// $ref is resolved before parsing, producing the correct schema
export const parcelSchema = z.object({
  id: z.number(),
  // ...
})

4.31.4

🐛 Bug Fixes

@kubb/plugin-oas

Fix paramsCasing: 'camelcase' dropping unchanged params from mappedParams

When a parameter schema contained a mix of snake_case and already-camelCase params (e.g. user_id and page), only the params whose names actually changed were included in mappedParams. This caused already-camelCase params to be silently dropped and never sent to the API.

Now, when paramsCasing: 'camelcase' is set and any transformation is needed, all params are included in the mapping so they are correctly forwarded to the API.

typescript
// Schema: { user_id, page } with paramsCasing: 'camelcase'
// mappedParams only contained user_id -> userId
// 'page' was missing and never sent to the API
const { userId } = params
// 'page' was silently dropped
typescript
// Schema: { user_id, page } with paramsCasing: 'camelcase'
// mappedParams contains both user_id -> userId AND page -> page
const { userId, page } = params
// Both params are correctly sent to the API

4.31.3

🐛 Bug Fixes

@kubb/plugin-mcp

Use registerTool helper and include structuredContent in MCP handler responses

MCP handlers now use the registerTool helper and return structuredContent: { data: res.data } alongside the existing content array, enabling richer structured output for MCP tool results.


4.31.2

📦 Dependencies

  • Upgrade Fabric

4.31.1

🐛 Bug Fixes

@kubb/oas

Restore separate schema generation for multi-file OpenAPI specs

When a main OpenAPI spec referenced external files (e.g. api-definitions.yml#/components/requestBodies/...), the bundler was inlining all external schemas rather than lifting them into #/components/schemas/. This caused getSchemas() to return nothing, so plugins like plugin-zod generated all schemas inline—no separate parcelSchema.ts, no contactDetailsTypeSchema.ts, etc.

A pre-bundling step now merges external file components/ sections into the main document before bundling, ensuring all named component schemas are preserved and separate schema files are generated as expected.


@kubb/plugin-client

Don't mutate config.signal, use it only if available

The generated queryFn no longer mutates the config object to assign signal. Instead, it spreads config and uses config.signal if already set, falling back to the signal provided by the query framework.

typescript
queryFn: async ({ signal }) => {
  if (!config.signal) {
    config.signal = signal
  }
  return findPetsByStatus({ stepId }, config)
},
typescript
queryFn: async ({ signal }) => {
  return findPetsByStatus({ stepId }, { ...config, signal: config.signal ?? signal })
},

4.31.0

✨ Features

@kubb/cli

Add anonymous telemetry

Anonymous telemetry has been added to the Kubb CLI to track usage data (command, plugins, version, duration, platform, Node.js version, and file count). No OpenAPI specs, file paths, plugin options, or secrets are ever collected.

Telemetry can be disabled at any time by setting:

  • DO_NOT_TRACK=1 – standard opt-out flag recognised by many developer tools (consoledonottrack.com)
  • KUBB_DISABLE_TELEMETRY=1 – Kubb-specific opt-out flag

🐛 Bug Fixes

@kubb/plugin-oas

Fix external $ref schema being incorrectly named "itemsSchema"

When bundle() deduplicates an external schema that is referenced in multiple places, it creates internal $ref pointers like #/paths/~1proposals/get/.../schema/items. The last path segment items was incorrectly used as the schema name (producing "itemsSchema" after the plugin suffix). These non-component internal refs are now resolved inline instead.


4.30.0

✨ Features

@kubb/plugin-react-query, @kubb/plugin-solid-query, @kubb/plugin-svelte-query, @kubb/plugin-swr, @kubb/plugin-vue-query

Remove unused fetch import when client plugin is active

When the client plugin is active, the unused fetch import is no longer generated in query/SWR hook files, resulting in cleaner output.

📖 Documentation

@kubb/plugin-client, @kubb/plugin-react-query, @kubb/plugin-solid-query, @kubb/plugin-svelte-query, @kubb/plugin-swr, @kubb/plugin-vue-query

Document required type exports for custom importPath

When using a custom client.importPath with query plugins (plugin-react-query, plugin-vue-query, plugin-svelte-query, plugin-solid-query, plugin-swr), the generated hooks import type Client, type RequestConfig, and type ResponseErrorConfig from that module. Previously this requirement was undocumented, causing unexpected TypeScript errors for users with custom clients that did not export the Client type.

Your custom client module must now explicitly export all three types:

client.ts
typescript
export type RequestConfig<TData = unknown> = { /* type properties omitted for brevity */ }
export type ResponseConfig<TData = unknown> = { /* type properties omitted for brevity */ }
export type ResponseErrorConfig<TError = unknown> = TError

// Required when using query plugins
export type Client = <TData, _TError = unknown, TVariables = unknown>(
  config: RequestConfig<TVariables>
) => Promise<ResponseConfig<TData>>

export const client: Client = async (config) => { /* ... */ }
export default client

See the importPath documentation for the full type definitions and a complete example.


4.29.1

🐛 Bug Fixes

@kubb/plugin-ts

Correct use of default (non-breaking change), this will change in v5


4.29.0

✨ Features

@kubb/core, @kubb/plugin-client, @kubb/plugin-ts, @kubb/plugin-zod, and more

Use of less packages and/or tiny libraries

Reduced the number of dependencies across all packages by replacing heavier libraries with smaller, purpose-built alternatives. This results in a total bundle size reduction of -6.7 MB.

💥 Breaking Changes

unplugin-kubb

Upgrade to Unplugin v3

unplugin-kubb has been updated to use unplugin v3, which introduces breaking changes to the plugin API. Please refer to the unplugin v3 migration guide if you are using unplugin-kubb directly.


4.28.1

🐛 Bug Fixes

@kubb/oas

Properties with application/octet-stream interpreted as Blob

Schemas with contentMediaType: application/octet-stream are interpreted as Blob.


4.28.0

✨ Features

@kubb/plugin-ts

Add integerType option to control int64 TypeScript type

Adds an integerType option that controls how OpenAPI integer fields with format: int64 are mapped to TypeScript types.

  • 'bigint' (default) — uses the TypeScript bigint type, accurate for values exceeding Number.MAX_SAFE_INTEGER.
  • 'number' — uses the TypeScript number type, matching the runtime behavior of JSON.parse().
typescript
pluginTs({
  integerType: 'number', // 'number' | 'bigint', default: 'bigint'
})

4.27.4

🔄 Refactors

@kubb/core, @kubb/plugin-client, @kubb/plugin-zod

Replace resolveModuleSource with static imports and build-time template inlining

Removed resolveModuleSource from @kubb/core/utils. Template file contents for @kubb/plugin-client (config, axios, fetch) and @kubb/plugin-zod (ToZod) are now inlined as string constants at build time via the importAttributeTextPlugin rolldown/tsdown plugin, using import ... with { type: 'text' } import attributes as the build-time marker. This eliminates all runtime filesystem reads for template sources.


4.27.3

🐛 Bug Fixes

@kubb/oas

Remove redocly and use @apidevtools/json-schema-ref-parser for OpenAPI bundling

Replaced @redocly/openapi-core with @apidevtools/json-schema-ref-parser to resolve MissingPointerError issues with $ref pointers (e.g., #/definitions/enumNames.Type). External file refs and URL refs are now properly resolved during OpenAPI parsing.


4.27.2

🐛 Bug Fixes

@kubb/agent

Replace dynamic imports with static imports in resolvePlugins

Replaced dynamic await import() calls in resolvePlugins with static imports for all supported kubb plugins to improve reliability and bundler compatibility.


4.27.0

✨ New Features

@kubb/cli

Add --allow-write and --allow-all flags to kubb agent start

Two new CLI flags (and corresponding environment variables) have been added to kubb agent start:

  • --allow-write / KUBB_AGENT_ALLOW_WRITE=true – opt-in to writing generated files to the filesystem. When not set, the kubb config runs with output.write: false and the Studio config patch is not persisted.
  • --allow-all / KUBB_AGENT_ALLOW_ALL=true – grant all permissions; implies --allow-write.

4.26.1

🐛 Bug Fixes

@kubb/cli

Update chokidar to fulfill provenance requirements in pnpm

Updated chokidar dependency in @kubb/cli to fulfill provenance requirements in pnpm.


4.26.0

✨ New Features

@kubb/plugin-zod

New guidType option for UUID/GUID generation

Added a new guidType option to control how OpenAPI format: uuid fields are generated in Zod schemas.

  • guidType accepts 'uuid' (default) and 'guid'
  • 'guid' is only applied when using Zod version: '4' (v3 falls back to UUID generation)

@kubb/plugin-mcp

Export startServer function

The startServer function is now exported from @kubb/plugin-mcp, allowing users to implement their own server logic and support additional transports instead of relying on auto-invocation.

🐛 Bug Fixes

@kubb/plugin-client

Fix default import for fetch in bundled mode

Fixed class client generators incorrectly using a default import for fetch in bundled mode when the bundled templates only have a named export.


4.25.0

✨ New Features

@kubb/agent

WebSocket integration for Kubb Studio connectivity

The Kubb Agent now supports bidirectional WebSocket communication with Kubb Studio. When KUBB_STUDIO_URL and KUBB_AGENT_TOKEN environment variables are configured, the agent automatically establishes a secure WebSocket connection on startup.

Key features:

  • Real-time event streaming: Generation progress and lifecycle events are streamed live to Studio
  • Command handling: Receives and executes generate and connect commands from Studio
  • Session management: Automatic session caching with 24-hour expiration for faster reconnects
  • Automatic reconnection: Persistent connection with configurable retry intervals and keep-alive pings
  • Secure authentication: SHA-512 token hashing for session storage
  • Graceful shutdown: Proper disconnect notifications when the agent stops

See the Agent documentation for setup instructions and environment variable configuration.


4.24.1

🐛 Bug Fixes

@kubb/plugin-ts

Add title property as the main comment

The title property of the schema is now interpreted as the "main comment" of type definitions.


4.23.0

✨ New Features

@kubb/plugin-client

Export mergeConfig from fetch and axios clients

Added mergeConfig export to both fetch and axios client templates, providing a utility function to merge client configurations programmatically.

🐛 Bug Fixes

@kubb/plugin-client

Fix class-style API clients silently discarding constructor configs

Class-style API clients were not properly applying constructor configurations. This has been fixed to ensure that configurations passed to the constructor are correctly applied to all client instances.


4.22.3

@kubb/plugin-faker

Fix data forwarding with enum

Faker's functions was passing data downstream, but it was failing with enums. It resulted in functions trying to pass data to functions not accepting any param. This has been fixed and now aligned with other raw types as numbers or strings.


4.22.2

🐛 Bug Fixes

@kubb/plugin-ts

Fix enumType: "asPascalConst" const naming breaking barrel exports

When using enumType: "asPascalConst", the generated const identifier incorrectly included the Key suffix, causing barrel exports to reference non-existent symbols. The const now uses the base name without the Key suffix, while the type alias correctly uses the name with the Key suffix.

Before:

typescript
export const GetPetsQueryParamsStatusEnumKey = { ... } as const // ❌ Wrong
export type GetPetsQueryParamsStatusEnumKey = ...               // Correct

After:

typescript
export const GetPetsQueryParamsStatusEnum = { ... } as const    // ✅ Correct
export type GetPetsQueryParamsStatusEnumKey = ...               // ✅ Correct

This fix ensures barrel exports work correctly by exporting the const with the proper name.


4.22.1

🐛 Bug Fixes

@kubb/cli, @kubb/core

Add npx kubb server


4.22.0

✨ New Features

@kubb/plugin-client

Add Client type alias to axios and fetch client templates

Added a Client type alias that provides better TypeScript support when working with generated client code. This makes it easier to reference the client type in your application code.

🐛 Bug Fixes

@kubb/oas

Replace dynamic import with static import for @redocly/openapi-core

Since @redocly/openapi-core is a declared dependency, using a static import is more appropriate for better performance and IDE support.

@kubb/plugin-faker

Top functions can now pass data down to functions called downstream

Improved the data flow in faker generators, allowing top-level functions to pass context and data to nested function calls for more flexible mock data generation.

📦 Dependencies

Externalize all @kubb/* packages in tsdown configs

Fixed TypeScript type incompatibility errors by externalizing all @kubb/* packages in tsdown configurations. This prevents duplicate type declarations across packages caused by inlined #private class fields.

Affected packages:

  • @kubb/oas
  • @kubb/plugin-client
  • @kubb/plugin-cypress
  • @kubb/plugin-faker
  • @kubb/plugin-mcp
  • @kubb/plugin-msw
  • @kubb/plugin-oas
  • @kubb/plugin-react-query
  • @kubb/plugin-redoc
  • @kubb/plugin-solid-query
  • @kubb/plugin-svelte-query
  • @kubb/plugin-swr
  • @kubb/plugin-ts
  • @kubb/plugin-vue-query
  • @kubb/plugin-zod

4.21.3

🐛 Bug Fixes

@kubb/oas

Replace dynamic import with static import for @redocly/openapi-core. Since the package is a declared dependency, using a static import is more appropriate for better performance and IDE support.


4.21.2

🐛 Bug Fixes

@kubb/cli, @kubb/core

Correct use of /api/health stream api


4.21.1

📦 Dependencies

Upgrade fabric.


4.21.0

✨ New Features

Parameter Casing Support

Added paramsCasing option to transform API parameter names to camelCase across all generated code while maintaining full API compatibility.

Affected Plugins:

Key Features:

  • ✅ Transform path, query, and header parameter names to camelCase
  • ✅ Automatic mapping back to original API names in HTTP requests
  • ✅ Full TypeScript type safety with indexed access types
  • ✅ Request/response bodies remain unchanged
  • ✅ Works across all query plugins consistently

Configuration Example:

typescript
import { defineConfig } from '@kubb/core'
import { pluginTs } from '@kubb/plugin-ts'
import { pluginClient } from '@kubb/plugin-client'
import { pluginReactQuery } from '@kubb/plugin-react-query'

export default defineConfig({
  plugins: [
    pluginTs({
      paramsCasing: 'camelcase',
    }),
    pluginClient({
      paramsCasing: 'camelcase',
    }),
    pluginReactQuery({
      paramsCasing: 'camelcase',
      client: {
        paramsCasing: 'camelcase',
      },
    }),
  ],
})

Before:

typescript
// Original API has: step_id, X-Custom-Header
export async function findPet(
  step_id: string,
  headers?: { 'X-Custom-Header'?: string }
) {
  return fetch(`/pet/${step_id}`)
}

After:

typescript
// With paramsCasing: 'camelcase'
export async function findPet(
  stepId: string,  // ✓ camelCase
  headers?: { xCustomHeader?: string }  // ✓ camelCase
) {
  const step_id = stepId  // Automatically mapped
  return fetch(`/pet/${step_id}`)  // Uses original API name
}

Learn More:


4.20.4

🐛 Bug Fixes

@kubb/plugin-ts

Fix asPascalConst enum const values not exported in barrel files


4.20.3

🐛 Bug Fixes

@kubb/plugin-zod

Fixed zod import to use namespace import for better compatibility

Changed from import z from 'zod' to import * as z from 'zod' to improve compatibility with different module systems and bundlers.


4.20.2

🐛 Bug Fixes

@kubb/cli, @kubb/core

Fixed offline support - version check no longer blocks code generation


4.20.1

🐛 Bug Fixes

@kubb/core, @kubb/plugin-oas

Preserve line breaks in JSDoc descriptions

Line breaks (\r\n, \n) in OpenAPI schema descriptions are now properly preserved in generated JSDoc comments. Previously, multi-line descriptions were being collapsed into single lines without whitespace separation.

Before:

typescript
/**
 * @description Creates a pet in the store.This is an arbitrary description with lots of formatting from the real world.- We like to make lists
 */

After:

typescript
/**
 * @description Creates a pet in the store.
 * This is an arbitrary description with lots of formatting from the real world.
 * - We like to make lists
 */

This restores the v3.18.3 behavior and ensures multi-line documentation is properly formatted in generated code.


4.20.0

✨ Features

@kubb/cli

New init command for interactive project setup

The CLI now includes a new kubb init command that provides an interactive setup wizard to quickly scaffold a Kubb project.

bash
npx kubb init

Features:

  • Interactive prompts - Guides you through essential configuration options
  • Package manager detection - Automatically detects npm, pnpm, yarn, or bun
  • Plugin selection - Multi-select from all 13 available Kubb plugins
  • Automatic installation - Installs selected packages with the detected package manager
  • Config generation - Creates kubb.config.ts with sensible defaults for selected plugins
  • File protection - Asks before overwriting existing configuration
  • Task-based progress - Clear visual feedback during installation and setup

The command guides you through:

  1. Creating a package.json (if needed)
  2. Selecting your OpenAPI specification path
  3. Choosing an output directory for generated files
  4. Selecting which plugins to install
  5. Installing packages automatically
  6. Generating a configured kubb.config.ts

This is now the recommended way to start a new Kubb project!

See the CLI documentation for more details.


4.19.2

📦 Dependencies

Update Fabric packages.


4.19.1

✨ Features

@kubb/plugin-oas

Enhanced collisionDetection to prevent nested enum name collisions

The collisionDetection option now prevents duplicate enum names when multiple schemas define identical inline enums in nested properties.

When enabled, Kubb tracks the root schema name throughout the parsing chain and includes it in enum naming for nested properties, ensuring unique enum names across different schemas.

yaml
components:
  schemas:
    NotificationTypeA:
      properties:
        params:
          type: object
          properties:
            channel:
              type: string
              enum:
                - public
                - collaborators

    NotificationTypeB:
      properties:
        params:
          type: object
          properties:
            channel:
              type: string
              enum:
                - public
                - collaborators
typescript
// ❌ Both files export the same enum - collision!
// NotificationTypeA.ts
export const paramsChannelEnum = {
  public: "public",
  collaborators: "collaborators"
} as const

// NotificationTypeB.ts
export const paramsChannelEnum = {  // Duplicate!
  public: "public",
  collaborators: "collaborators"
} as const
typescript
// ✅ Unique enum names - no collision
// NotificationTypeA.ts
export const notificationTypeAParamsChannelEnum = {
  public: "public",
  collaborators: "collaborators"
} as const

// NotificationTypeB.ts
export const notificationTypeBParamsChannelEnum = {
  public: "public",
  collaborators: "collaborators"
} as const

How to enable:

typescript
// kubb.config.ts
export default defineConfig({
  plugins: [
    pluginOas({
      collisionDetection: true,  // Recommended - prevents all collision types
    }),
  ],
})

TIP

This enhancement is backward compatible and only activates when collisionDetection: true. It's recommended to enable this option to prepare for Kubb v5, where it will be the default.


4.19.0

✨ Features

@kubb/plugin-oas

Added collisionDetection option to prevent schema name conflicts

New opt-in collisionDetection option intelligently handles name collisions when OpenAPI specs contain schemas with the same name (case-insensitive) across different components.

typescript
// kubb.config.ts
export default defineConfig({
  plugins: [
    pluginOas({
      collisionDetection: true,  // Enable collision detection
    }),
  ],
})

How it works:

Cross-component collisions add semantic suffixes:

yaml
components:
  schemas:
    Order:
      type: object
      properties:
        id: { type: string }

  requestBodies:
    Order:
      content:
        application/json:
          schema:
            type: object
            properties:
              items: { type: array }
typescript
// ✅ No conflicts - semantic suffixes added
export type OrderSchema = { id: string }
export type OrderRequest = { items: unknown[] }
typescript
// ❌ May cause duplicate files or overwrite issues
export type Order = { id: string }
export type Order = { items: unknown[] }  // Collision!

Same-component collisions add numeric suffixes:

yaml
components:
  schemas:
    Variant: { type: string, enum: [A, B] }
    variant: { type: string, enum: [X, Y] }
typescript
// ✅ Deterministic numeric suffixes
export type Variant = 'A' | 'B'
export type Variant2 = 'X' | 'Y'

NOTE

This option is disabled by default to preserve backward compatibility. It will become the default in Kubb v5.


4.18.5

🐛 Bug Fixes

@kubb/plugin-zod

Improved nullable schema handling in OpenAPI 3.1

Improved handling of nullable schemas in OpenAPI 3.1 by properly recognizing type: null variants. Previously, some nullable schema patterns were not correctly identified, causing incorrect Zod schema generation.

NOTE

This fix implements the solution from #2362.


@kubb/plugin-zod

Fixed incorrect omit usage on z.union schemas

Fixed an issue where .omit() was being applied to z.union() schemas, which is not valid in Zod. The plugin now correctly avoids using omit on union types.

NOTE

This fix implements the solution from #2368.


4.18.4

✨ Features

@kubb/cli

Added Kubb mascot logo to CLI welcome message

The CLI now displays an improved welcome message featuring the Kubb mascot character with colorful gradients and a cleaner layout. This provides a more engaging and branded experience when using the Kubb CLI.


4.18.3

✨ Features

@kubb/cli

Added Kubb mascot logo to CLI welcome message

The CLI now displays an improved welcome message featuring the Kubb mascot character with colorful gradients and a cleaner layout. This provides a more engaging and branded experience when using the Kubb CLI.


4.18.2

🐛 Bug Fixes

@kubb/plugin-ts

Fixed missing export for asPascalConst enum type aliases

When using enumType: 'asPascalConst', the generated type alias was not exported, preventing consuming code from importing the type. TypeScript allows values and types with identical names to coexist in separate namespaces, so both can be safely exported.

typescript
// Generated enum const
export const PetType = {
  Dog: 'dog',
  Cat: 'cat',
} as const
type PetType = (typeof PetType)[keyof typeof PetType] // ❌ Not exported!
typescript
// Generated enum const
export const PetType = {
  Dog: 'dog',
  Cat: 'cat',
} as const
export type PetType = (typeof PetType)[keyof typeof PetType] // ✅ Now exported!

@kubb/plugin-faker

Fixed incorrect spreading of factory functions in allOf schemas with single refs

When using allOf with a single reference to a primitive type (e.g., enum), the generated factory code was incorrectly spreading the result. This has been fixed so that single refs in allOf are no longer spread, while multiple refs continue to be spread correctly.

typescript
// Generated factory for enum type
export function createIssueCategory() {
  faker.seed([100])
  return faker.helpers.arrayElement(['close out', 'something needed', 'safety', 'progress'])
}

// Parent object incorrectly spreading the enum factory
export function createTestObject() {
  return {
    category: { ...createIssueCategory() }, // ❌ Spreading a string value!
  }
}
typescript
// Generated factory for enum type (unchanged)
export function createIssueCategory() {
  faker.seed([100])
  return faker.helpers.arrayElement(['close out', 'something needed', 'safety', 'progress'])
}

// Parent object correctly using the enum factory
export function createTestObject() {
  return {
    category: createIssueCategory(), // ✅ No spreading!
  }
}

NOTE

This fix resolves the issue reported in #1767 where nullable enum types were being incorrectly spread.


4.18.1

🐛 Bug Fixes

@kubb/plugin-faker

Fixed infinite recursion for self-referencing types

Fixed a critical issue where self-referencing types (e.g., Node with children: Node[]) caused infinite recursion and "Maximum call stack size exceeded" errors. The plugin now detects self-references and safely returns undefined instead of making recursive calls.

typescript
// Self-referencing type caused infinite recursion
export function node(data?: Partial<Node>): Node {
  return {
    ...{ id: faker.string.alpha(), children: faker.helpers.multiple(() => node()) }, // ❌ Stack overflow!
    ...(data || {}),
  }
}
typescript
// Safe handling of self-references
export function node(data?: Partial<Node>): Node {
  return {
    ...{ id: faker.string.alpha(), children: faker.helpers.multiple(() => undefined) }, // ✅ Safe!
    ...(data || {}),
  }
}

// Users can still override with actual data:
const myNode = node({ children: [{ id: 'child1' }] })

NOTE

This fix implements the solution proposed in #ISSUE_NUMBER.


4.18.0

✨ Features

@kubb/plugin-client

Static class client generation

Added support for generating API clients as classes with static methods using clientType: 'staticClass'. This allows you to call API methods directly on the class without instantiating it:

typescript
const client = new Pet()
await client.getPetById({ petId: 1 })
typescript
await Pet.getPetById({ petId: 1 })

To enable, set clientType: 'staticClass' in your pluginClient options. See the plugin-client documentation for details and usage notes.

NOTE

This feature implements #2326.


4.17.2

🐛 Bug Fixes

Multiple Plugins

Fixed QueryKey default values for array and union request body types

Fixed an issue where QueryKey functions and client functions incorrectly assigned = {} as the default parameter value for all optional request body parameters, causing TypeScript error TS2322 when the schema type was an array or a discriminated union with required fields.

Affected plugins:

Changes:

  • Array types now correctly use = [] as default
  • Union types (anyOf/oneOf) with required fields now have no default value
  • Union types with all-optional variants use = {}
  • Object types with optional fields continue to use = {}

Code improvements:

  • Added shared getDefaultValue() utility function to @kubb/oas for determining appropriate default values based on schema type
  • Eliminated 515 lines of duplicated code across all affected plugins
  • Single source of truth ensures consistent behavior
typescript
// Array type - incorrect default
export const getUsersByIdsQueryKey = (
  data: string[] = {},  // ❌ TS2322 error
) => [{ url: '/users/batch' }, ...(data ? [data] : [])] as const

// Union type with required fields - incorrect default
export const filterItemsQueryKey = (
  data: FilterByCategory | FilterByTag = {},  // ❌ TS2322 error
) => [{ url: '/items/filter' }, ...(data ? [data] : [])] as const
typescript
// Array type - correct default
export const getUsersByIdsQueryKey = (
  data: string[] = [],  // ✅ Correct!
) => [{ url: '/users/batch' }, ...(data ? [data] : [])] as const

// Union type with required fields - no default
export const filterItemsQueryKey = (
  data: FilterByCategory | FilterByTag,  // ✅ Correct!
) => [{ url: '/items/filter' }, ...(data ? [data] : [])] as const

4.17.1

🐛 Bug Fixes

@kubb/plugin-oas

Update packages

4.17.0

✨ Features

@kubb/plugin-ts and @kubb/core

Configurable enum key casing

Added a new enumKeyCasing option to @kubb/plugin-ts that allows you to control how enum key names are generated. This improves code readability and allows you to use conventional dot-notation syntax instead of bracket notation when accessing enum values.

New transformers in @kubb/core:

  • screamingSnakeCase: Converts to SCREAMING_SNAKE_CASE
  • snakeCase: Converts to snake_case

New option in @kubb/plugin-ts:

The enumKeyCasing option supports the following values:

  • 'screamingSnakeCase': ENUM_VALUE (recommended for TypeScript enums)
  • 'snakeCase': enum_value
  • 'pascalCase': EnumValue
  • 'camelCase': enumValue
  • 'none': Uses the enum value as-is (default, preserves backward compatibility)
typescript
// kubb.config.ts
export default {
  plugins: [
    pluginTs({
      enumType: 'enum',
      enumKeyCasing: 'screamingSnakeCase',
    }),
  ],
}
typescript
export const enumStringEnum = {
  'created at': 'created at',
  'FILE.UPLOADED': 'FILE.UPLOADED',
} as const

// Usage requires bracket syntax
const value = enumStringEnum['created at']
typescript
export const enumStringEnum = {
  CREATED_AT: 'created at',
  FILE_UPLOADED: 'FILE.UPLOADED',
} as const

// Usage with clean dot-notation syntax
const value = enumStringEnum.CREATED_AT

Additional improvements:

  • Enum member keys now use identifiers without quotes when the key is a valid JavaScript identifier, making the output cleaner and more idiomatic
  • Default value is 'none' to preserve existing behavior and ensure backward compatibility

🐛 Bug Fixes

@kubb/plugin-oas

Removed incorrect enumSuffix warning

Fixed an issue where setting enumSuffix: '' in plugin configuration would trigger a misleading warning message ℹ EnumSuffix set to an empty string does not work. The feature actually works correctly - empty string suffixes are fully supported and tested. The incorrect warning has been removed.

4.16.0

✨ Features

MCP Support

Kubb now includes support for the Model Context Protocol (MCP), enabling AI assistants and tools to interact with your OpenAPI specifications programmatically.

NOTE

The Kubb MCP server allows AI assistants like Claude Desktop to read, analyze, and generate code from OpenAPI specifications using the standardized MCP interface.

TIP

To use the Kubb MCP server, install @kubb/mcp and run npx @kubb/mcp or kubb mcp

4.15.2

🐛 Bug Fixes

@kubb/plugin-react-query

No empty object should be passed if all parameters are optional

4.15.1

🐛 Bug Fixes

@kubb/plugin-ts

Fixed TS2411 error in QueryParams with mixed property types

Fixed TypeScript compilation errors (TS2411) that occurred when generated QueryParams types combined typed properties (enums, objects) with dynamic parameters from additionalProperties (when using style: form with explode: true).

Root Cause:

The parser always used the specific additionalProperties type for index signatures, creating [key: string]: string that conflicts with non-string typed properties.

Solution:

When typed properties and additionalProperties coexist, use [key: string]: unknown for the index signature. This preserves type safety while avoiding conflicts.

typescript
export type QueryParams = {
  include?: 'author' | 'tags';    // ❌ TS2411: not assignable to string
  page?: { number?: number };      // ❌ TS2411: not assignable to string
  sort?: string;
  [key: string]: string;           // 💥 Conflicts with typed properties
};
typescript
export type QueryParams = {
  include?: 'author' | 'tags';     // ✅ Compatible with unknown
  page?: { number?: number };      // ✅ Compatible with unknown
  sort?: string;
  [key: string]: unknown;          // ✅ No conflicts
};

Impact:

  • No breaking changes - backward compatible
  • Only affects types with both typed properties and additionalProperties
  • Types with only additionalProperties remain unchanged

4.15.0

✨ Features

@kubb/plugin-react-query

Custom TanStack Query hook options support

Added support for custom TanStack Query hook options through the new customOptions configuration. This allows you to inject custom behavior into generated hooks such as query invalidation, custom error handling, or any other TanStack Query options you need to customize globally.

Key features:

  • Type-safe customization: Generates a HookOptions type for full type safety when implementing custom hook options
  • Per-hook customization: Customize options for individual hooks based on hookName or operationId
  • Flexible integration: Use any custom logic in your hook (access query client, implement error handling, etc.)
typescript
// kubb.config.ts
import { defineConfig } from '@kubb/core'
import { pluginReactQuery } from '@kubb/plugin-react-query'

export default defineConfig({
  plugins: [
    pluginReactQuery({
      customOptions: {
        importPath: './hooks/useCustomHookOptions.ts',
        name: 'useCustomHookOptions', // optional, defaults to 'useCustomHookOptions'
      },
    }),
  ],
})
typescript
// hooks/useCustomHookOptions.ts
import { useQueryClient } from '@tanstack/react-query'
import type { HookOptions } from './gen/HookOptions' // Generated type

export function useCustomHookOptions<T extends keyof HookOptions>({
  hookName,
  operationId
}: {
  hookName: T
  operationId: string
}): HookOptions[T] {
  const queryClient = useQueryClient()

  // Example: Invalidate related queries on mutation
  const customOptions = {
    useFindPetById: {
      onSuccess: () => {
        queryClient.invalidateQueries({ queryKey: ['pets'] })
      },
    },
    // ... more custom options for other hooks
  }

  return customOptions[hookName] ?? {}
}
typescript
// Generated hook will automatically use custom options
export function useFindPetById(petId: string, options?: QueryOptions) {
  const customOptions = useCustomHookOptions({
    hookName: 'useFindPetById',
    operationId: 'findPetById'
  })

  return useQuery({
    ...findPetByIdQueryOptions(petId),
    ...customOptions, // Custom options are applied here
    ...options,
  })
}

Use cases:

  • Automatically invalidate related queries on mutations
  • Implement global error handling for specific operations
  • Add retry logic based on operation type
  • Inject analytics or logging into query lifecycle
  • Configure staleTime/cacheTime per operation category

Type Safety

The generated HookOptions type ensures your custom hook implementation is type-safe and includes all generated hooks (queries, mutations, suspense queries, and infinite queries).

NOTE

This feature is available for @kubb/plugin-react-query in v4.15.0. Similar support for other query plugins (Vue Query, Solid Query, Svelte Query, SWR) may be added in future releases.


4.14.1

🚀 Performance Improvements

Achieved 18-27% performance improvement for OpenAPI code generation through advanced optimizations including increased parallelism and schema caching.

@kubb/plugin-oas

Increased Processing Parallelism:

  • Operation processing concurrency increased from 10 to 30 concurrent operations
  • Schema processing concurrency increased from 10 to 30 concurrent schemas
  • Generator parallelism increased from 1 to 3 concurrent generators

Added Schema Caching:

  • Implemented schema parse caching to eliminate redundant parsing

Performance Impact

These optimizations provide:

  • 10-15% faster operation processing
  • 8-12% faster schema generation
  • 3-5% reduction from schema caching
  • Overall: 18-27% faster code generation

@kubb/core

Improved Parallelism:

  • PluginManager concurrency increased from 5 to 15 for better parallel plugin execution
  • Better resource utilization on multi-core systems
  • 4-7% performance improvement

Compatibility

All changes are backward compatible with no breaking changes to APIs or plugin behavior.

@kubb/plugin-ts

New inlineLiteral enum type for cleaner TypeScript definitions

Added inlineLiteral as a new value for the enumType option, allowing enum values to be inlined directly into type properties instead of generating separate enum declarations.

typescript
export const petStatusEnum = {
  available: 'available',
  pending: 'pending',
  sold: 'sold',
} as const

export type PetStatusEnumKey = (typeof petStatusEnum)[keyof typeof petStatusEnum]

export interface Pet {
  status?: PetStatusEnumKey
}
typescript
export interface Pet {
  status?: "available" | "pending" | "sold"
}

Usage:

typescript
pluginTs({
  enumType: 'inlineLiteral',
})

NOTE

In Kubb v5, inlineLiteral will become the default enumType.


All notable changes to Kubb are documented here. Each version is organized with clear categories (Features, Bug Fixes, Breaking Changes, Dependencies) and includes code examples where applicable. Use the outline navigation in the right sidebar to quickly jump to any version.

  • Features - New functionality and enhancements
  • 🐛 Bug Fixes - Bug fixes and corrections
  • 🚀 Breaking Changes - Changes that may require code updates
  • 📦 Dependencies - Package updates and dependency changes

TIP

Use the outline navigation (right sidebar) to quickly jump to specific versions.

4.14.0

✨ Features

@kubb/plugin-ts

Added arrayType option to switch between Array<Type> and Type[] syntax for array types.

typescript
type Pet = {
  tags: string[]
}
typescript
type Pet = {
  tags: Array<string>
}

4.13.1

🐛 Bug Fixes

@kubb/plugin-ts

Fixed TypeScript Printer Crash with Object Prototype Property Names

Resolved a critical issue where schemas containing properties named after JavaScript built-in methods (e.g., toString, valueOf, hasOwnProperty) would crash the TypeScript printer with "Debug Failure. Unhandled SyntaxKind: Unknown".

Root Cause:

The mapper lookup was using bracket notation (options.mapper?.[mappedName]), which searches the entire prototype chain. For property names like "toString", it would find Object.prototype.toString and treat it as a custom mapping function instead of creating a proper TypeScript property signature.

Solution:

Changed the mapper check to use Object.prototype.hasOwnProperty.call() to only match user-defined mapper properties:

typescript
// Matches inherited properties from Object.prototype
if (options.mapper?.[mappedName]) {
  return options.mapper?.[mappedName]  // Returns Object.prototype.toString
}
typescript
// Only matches own properties, not inherited ones
if (options.mapper && Object.prototype.hasOwnProperty.call(options.mapper, mappedName)) {
  return options.mapper[mappedName]
}

Affected Schemas:

This bug affected any OpenAPI schema with properties named after JavaScript built-in methods, including:

  • toString
  • valueOf
  • hasOwnProperty
  • constructor
  • Other Object.prototype methods

Example Schema:

yaml
components:
  schemas:
    ChangeItemBean:
      type: object
      properties:
        field: { type: string }
        toString: { type: string }  # Previously crashed, now works
        valueOf: { type: string }    # Previously crashed, now works

4.13.0

✨ Features

@kubb/cli, @kubb/core

Auto-Detection for Formatters and Linters

Added 'auto' option for both output.format and output.lint configurations. When set to 'auto', Kubb automatically detects and uses available tools, eliminating the need to explicitly specify which formatter or linter to use.

Format Auto-Detection:

When format: 'auto' is set, Kubb checks for formatters in this order:

  1. biome (first choice)
  2. oxfmt (second choice)
  3. prettier (third choice)
typescript
export default defineConfig({
  input: { path: './petStore.yaml' },
  output: {
    path: './src/gen',
    format: 'prettier', // Had to specify which formatter
  },
})
typescript
export default defineConfig({
  input: { path: './petStore.yaml' },
  output: {
    path: './src/gen',
    format: 'auto', // Automatically detects biome or oxfmt or prettier
  },
})

Lint Auto-Detection:

When lint: 'auto' is set, Kubb checks for linters in this order:

  1. biome (first choice)
  2. oxlint (second choice)
  3. eslint (third choice)
typescript
export default defineConfig({
  input: { path: './petStore.yaml' },
  output: {
    path: './src/gen',
    lint: 'eslint', // Had to specify which linter
  },
})
typescript
export default defineConfig({
  input: { path: './petStore.yaml' },
  output: {
    path: './src/gen',
    lint: 'auto', // Automatically detects biome, oxlint, or eslint
  },
})

Combined Usage:

typescript
export default defineConfig({
  input: { path: './petStore.yaml' },
  output: {
    path: './src/gen',
    format: 'auto', // Detects biome or prettier
    lint: 'auto',   // Detects biome, oxlint, or eslint
  },
})

If no formatter or linter is detected, Kubb will emit a warning and skip the respective operation, ensuring your build continues smoothly.

TIP

This feature provides a convenient default for users who want formatting/linting without having to configure which specific tool to use. The detection uses the --version flag to check tool availability.

4.12.13

🐛 Bug Fixes

@kubb/cli

Fixed module resolution issue when loading TypeScript configuration files. Previously, jiti used the CLI's installation location for module resolution, which could cause errors like Cannot find module './_baseIsArguments' when the user's config imported Kubb plugins. Now jiti correctly resolves modules relative to the config file's location, matching standard Node.js module resolution behavior.

INFO

This fix resolves issues where users encountered module resolution errors when running npx kubb generate with a kubb.config.ts file that imports Kubb plugins.

4.12.11

✨ Features

@kubb/oas, @kubb/plugin-oas

Comprehensive discriminator improvements with full OpenAPI 3.0 and 3.1 compliance.

Inline Schema Support:

Discriminators now work with inline schemas in oneOf/anyOf, not just $ref references:

yaml
components:
  schemas:
    Response:
      discriminator:
        propertyName: status
      oneOf:
        - type: object
          title: Success
          properties:
            status:
              const: success
            data:
              type: object
        - type: object
          title: Error
          properties:
            status:
              const: error
            message:
              type: string
typescript
export type Response =
  | {
      status?: "success"
      data?: object
    }
  | {
      status?: "error"
      message?: string
    }

Extension Property Discriminators:

Support for extension properties as discriminator names (e.g., x-linode-ref-name):

yaml
components:
  schemas:
    Data:
      discriminator:
        propertyName: x-response-type
      oneOf:
        - type: object
          x-response-type: Success
          properties:
            result:
              type: object
        - type: object
          x-response-type: Error
          properties:
            error:
              type: string
typescript
export type Data =
  | {
      result?: object
    }
  | {
      error?: string
    }

Extension properties are treated as metadata and don't generate runtime validation constraints.

Additional Improvements:

  • ✅ Const and single-value enum support for discriminator values
  • ✅ Mixed $ref and inline schemas in the same oneOf/anyOf
  • ✅ Title fallback for inline schemas without explicit discriminator values
  • ✅ Inferred mapping when explicit mapping not provided
  • ✅ Support for both oneOf and anyOf constructs
  • ✅ Synthetic ref handling with bounds validation
  • ✅ Error handling for invalid schema references

Supported Patterns:

All discriminator patterns from OpenAPI 3.0 and 3.1 specifications are now supported:

  • With explicit mapping
  • Without mapping (inferred from schema names)
  • oneOf and anyOf constructs
  • Strict and inherit modes
  • Inline schemas
  • Extension properties (x-*)
  • Const values
  • Single-value enums
  • Mixed $ref and inline schemas

Documentation:

See Discriminators in the knowledge base for comprehensive examples and patterns.

4.12.10

@kubb/oas, @kubb/plugin-ts

🐛 Bug Fixes

Better patternProperties handling for type generation.

4.12.9

🐛 Bug Fixes

@kubb/plugin-oas

Flatten allof to support better Zod schemas

4.12.8

🐛 Bug Fixes

@kubb/cli

Support for --silent flag to set LogLevel to silent.

4.12.7

🐛 Bug Fixes

@kubb/plugin-oas

Only validate once

4.12.6

✨ Features

Development Tooling

Added Knip for unused code detection to help maintain code quality and identify unused exports, dependencies, and files across the monorepo.

Usage:

bash
# Run Knip to detect unused code
pnpm run knip

# Run Knip in production mode
pnpm run knip:production

The configuration is defined in knip.json at the repository root and automatically ignores examples, e2e tests, and documentation workspaces.

4.12.5

✨ Features

Performance Optimizations

Improved performance across the core and OAS packages with several key optimizations:

@kubb/oas

Replaced inefficient JSON deep cloning with native structuredClone() API. The previous JSON.parse(JSON.stringify()) approach was significantly slower and more memory-intensive, especially for large OpenAPI documents.

typescript
const api: OasTypes.OASDocument = JSON.parse(JSON.stringify(config.input.data));
typescript
const api: OasTypes.OASDocument = structuredClone(config.input.data);

@kubb/core

  1. Plugin Lookup Optimization: Eliminated O(n*m) complexity in barrel file generation by creating a plugin key Map before nested loops, replacing expensive array spreading and linear searches with O(1) Map lookups.

  2. Object Spreading: Replaced repeated object spreading with Object.assign() in plugin context initialization, preventing unnecessary object allocations on each loop iteration.

  3. Array Operations: Optimized filter-map chains to use single-pass reduce(), eliminating redundant array iterations when processing settled promises.

These optimizations provide measurable performance improvements when generating code from large OpenAPI specifications with many plugins and files.

4.12.4

🐛 Bug Fixes

@kubb/plugin-oas

Fixed handling of empty schema objects {} in anyOf, oneOf, and allOf constructs.

Empty schema objects ({}) in JSON Schema represent "accepts any value" per the specification, but were being incorrectly filtered out from unions and intersections. This caused schemas like anyOf: [{}, {type: "null"}] to generate only null instead of the correct unknown | null.

typescript
export type ParameterBinding = {
  /**
   * @description The fixed value when source is FIXED.
   */
  fixed_value?: null; // Missing unknown type
};
typescript
export type ParameterBinding = {
  /**
   * @description The fixed value when source is FIXED.
   */
  fixed_value?: unknown | null; // Correct union type
};

The fix ensures that empty schemas are properly preserved as the configured unknownType (or emptySchemaType) in the generated types, matching the JSON Schema specification.

4.12.3

🐛 Bug Fixes

@kubb/oas, @kubb/plugin-ts, @kubb/plugin-zod, @kubb/plugin-faker

Fixed handling of query parameters with explode: true and style: form for objects with additionalProperties.

When a query parameter has style: "form", explode: true, and a schema with type: "object" and additionalProperties but no defined properties, the parameter is now correctly flattened to have additionalProperties at the root level instead of being nested as a property.

typescript
export type SystemsQueryParams = {
  /**
   * @description Custom fields
   * @type object | undefined
   */
  customFields?: {
    [key: string]: string;
  };
};
typescript
export type SystemsQueryParams = {
  [key: string]: string;
};

This matches the OpenAPI specification where explode: true causes object properties to be expanded as separate query parameters at the root level.

4.12.2

🐛 Bug Fixes

@kubb/plugin-ts

Added TypeScript as a peerDependency to ensure proper compatibility with the mapper option. The mapper feature uses TypeScript's compiler API (specifically ts.PropertySignature and factory methods), which requires TypeScript to be installed in the consuming project.

WARNING

If you're using the mapper option in @kubb/plugin-ts, ensure you have TypeScript >=5.9.0 installed in your project.

json
{
  "dependencies": {
    "@kubb/plugin-ts": "^4.12.2",
    "typescript": "^5.9.3"
  }
}

4.12.1

🐛 Bug Fixes

@kubb/plugin-cypress, @kubb/plugin-msw

Uses backticks so that the baseUrl can be set to a dynamic value (like an environment variable).

typescript
// Generated with single quotes - static string
const baseUrl = "https://api.example.com";
typescript
// Generated with backticks - allows template literals
const baseUrl = `https://api.example.com`;
// Now you can use: const baseUrl = `${process.env.API_URL}`

4.12.0

✨ Features

@kubb/cli, @kubb/core

Replace cli-progress and consola with @clack/prompts for modern interactive progress bars. Introduces flexible logger pattern with Claude-inspired CLI and GitHub Actions support.

Key features:

  • Event-driven logging architecture with KubbEvents
  • Multiple logger implementations that adapt to different environments:
    • Clack Logger - Modern interactive CLI with animated progress bars
    • GitHub Actions Logger - CI-optimized with collapsible sections (::group:: annotations)
    • Plain Logger - Simple text output for basic terminals
    • File System Logger - Writes logs to files
  • Custom logger support via defineLogger API
  • Automatic logger selection based on environment detection
typescript
import { defineLogger, LogLevel } from "@kubb/core";

export const customLogger = defineLogger({
  name: "custom",
  install(context, options) {
    const logLevel = options?.logLevel || LogLevel.info;

    context.on("lifecycle:start", (version) => {
      console.log(`Starting Kubb ${version}`);
    });

    context.on("plugin:start", (plugin) => {
      console.log(`Generating ${plugin.name}`);
    });

    context.on("plugin:end", (plugin, { duration }) => {
      console.log(`${plugin.name} completed in ${duration}ms`);
    });

    context.on("error", (error) => {
      console.error(error.message);
    });
  },
});

New KubbEvents:

  • lifecycle:start - Emitted at the beginning of the Kubb lifecycle
  • lifecycle:end - Emitted at the end of the Kubb lifecycle
  • config:start - Emitted when configuration loading starts
  • config:end - Emitted when configuration loading completes
  • generation:start - Emitted when code generation phase starts
  • generation:end - Emitted when code generation phase completes
  • generation:summary - Emitted with generation results summary
  • format:start / format:end - Code formatting events
  • lint:start / lint:end - Linting events
  • hook:start / hook:end / hook:execute - Hook execution events
  • plugin:start / plugin:end - Plugin execution events
  • files:processing:start / file:processing:update / files:processing:end - File processing events
  • info / success / warn / error / debug - Log message events
  • version:new - New version available notification

4.11.2

🐛 Bug Fixes

@kubb/oas

Fixed issue with uninitialized oasClass causing errors during OpenAPI schema processing.

4.11.0

✨ Features

  • @kubb/plugin-oas, @kubb/plugin-zod, @kubb/plugin-ts, @kubb/plugin-faker - Shared createParser helper for reduced code duplication

    Introduces createParser helper in @kubb/plugin-oas to eliminate parser duplication across Zod, TypeScript, and Faker plugins. Each parser previously reimplemented ~300 lines of schema traversal logic. Parsers are now ~150-200 lines instead of ~400-500 lines.

    Key features:

    • Framework accepting keyword mapper + custom handlers for parser-specific logic
    • Handlers can use this.parse for recursive parsing (via Function.call())
    • Exports findSchemaKeyword utility for constraint lookup in sibling schemas
    • Function syntax for handlers to enable this keyword usage
    typescript
    export const parse = createParser<string, ParserOptions>({
      mapper: zodKeywordMapper,
      handlers: {
        string(tree, options) {
          const minSchema = findSchemaKeyword(tree.siblings, "min");
          const maxSchema = findSchemaKeyword(tree.siblings, "max");
          return zodKeywordMapper.string(
            shouldCoerce(options.coercion, "strings"),
            minSchema?.args,
            maxSchema?.args,
            options.mini,
          );
        },
        union(tree, options) {
          const { current } = tree;
          return zodKeywordMapper.union(
            sort(current.args)
              .map((it) => this.parse({ ...tree, current: it }, options))
              .filter(Boolean),
          );
        },
      },
    });

🚀 Breaking Changes

  • @kubb/plugin-oas - Type renames for clarity

    Internal types are used during schema parsing. Most users won't be affected unless directly importing these types from @kubb/plugin-oas.

4.10.1

📦 Dependencies

Upgrade tsdown.

4.10.0

🐛 Bug Fixes

  • @kubb/plugin-ts - Restore asPascalConst enumType option

    The asPascalConst enumType option is no longer deprecated. This option generates enum-like constants with PascalCase names, providing an alternative to the default asConst which uses camelCase.

    typescript
    const petType = {
      Dog: "dog",
      Cat: "cat",
    } as const;
    
    type PetTypeKey = (typeof petType)[keyof typeof petType];
    typescript
    const PetType = {
      Dog: "dog",
      Cat: "cat",
    } as const;
    
    type PetType = (typeof PetType)[keyof typeof PetType];

4.9.4

🐛 Bug Fixes

  • plugin-oas - Fix allOf failing to merge constraints like maxLength with $ref schemas

    When using allOf to combine a $ref schema with an inline schema containing only constraints (like maxLength, minLength, pattern, etc.), those constraints were being lost in the generated schema tree. This affected generated TypeScript types and validation schemas (Zod, etc.).

    The issue occurred in two places:

    1. The allOf parser was using map(...)[0] which only kept the type keyword and discarded constraint schemas in baseItems
    2. Schemas without explicit type fields would return emptyType without preserving constraints
    yaml
    components:
      schemas:
        PhoneNumber:
          type: string
          pattern: '^(\+\d{1,3}[-\s]?)?.*$'
        PhoneWithMaxLength:
          allOf:
            - $ref: "#/components/schemas/PhoneNumber"
            - maxLength: 15 # ❌ This constraint was lost
    typescript
    // Generated Zod schema was missing .max(15)
    export const phoneWithMaxLengthSchema = z
      .string()
      .regex(/^(\+\d{1,3}[-\s]?)?.*$/);
    // Missing: .max(15)
    typescript
    // Generated Zod schema correctly includes .max(15)
    export const phoneWithMaxLengthSchema = z
      .string()
      .regex(/^(\+\d{1,3}[-\s]?)?.*$/)
      .max(15); // ✅ Now correctly included

4.9.3

🐛 Bug Fixes

  • Query Plugins - Fix mutation: false option being ignored

    Fix mutation: false option being ignored in all TanStack Query plugins (@kubb/plugin-react-query, @kubb/plugin-vue-query, @kubb/plugin-solid-query, @kubb/plugin-svelte-query, @kubb/plugin-swr).

    When mutation: false was set in plugin configuration, mutation hooks were still being generated. This occurred because the plugin was spreading the false value into an object with default configuration values instead of checking for it explicitly.

    typescript
    import { defineConfig } from "@kubb/core";
    import { pluginReactQuery } from "@kubb/plugin-react-query";
    
    export default defineConfig({
      plugins: [
        pluginReactQuery({
          mutation: false, // ❌ Was still generating mutation hooks
        }),
      ],
    });
    typescript
    import { defineConfig } from "@kubb/core";
    import { pluginReactQuery } from "@kubb/plugin-react-query";
    
    export default defineConfig({
      plugins: [
        pluginReactQuery({
          mutation: false, // ✅ Now properly prevents mutation hook generation
          query: true, // Only generates queryOptions
        }),
      ],
    });

    Changes:

    • Added explicit mutation === false check in plugin initialization before setting defaults, matching the existing query: false pattern
    • Added options.mutation !== false guard to isMutation condition in mutation generators
    • Updated vitest configs to support #mocks import alias for testing

4.9.2

🐛 Bug Fixes

  • plugin-swr - Add new paramsToTrigger option for mutations.

When set to true, mutation parameters (path params, query params, headers, request body) are passed via trigger({ petId, data, params, headers }) instead of requiring them as hook function arguments.

This aligns with React Query's mutation pattern.

TIP

This will become the default behavior in v5. Set mutation.paramsToTrigger: true to opt-in early.

4.9.1

🐛 Bug Fixes

  • Query Plugins - Fix clientType: 'class' compatibility

    Fix clientType: 'class' compatibility with query plugins (@kubb/plugin-react-query, @kubb/plugin-vue-query, @kubb/plugin-solid-query, @kubb/plugin-svelte-query, @kubb/plugin-swr).

    Previously, when @kubb/plugin-client was configured with clientType: 'class', query plugins would fail to generate proper hooks because they expected function-based clients but found class-based ones instead.

    Query plugins now automatically detect when clientType: 'class' is set and generate their own inline function-based clients, allowing class-based clients and query hooks to coexist in the same configuration.

    typescript
    import { defineConfig } from "@kubb/core";
    import { pluginClient } from "@kubb/plugin-client";
    import { pluginOas } from "@kubb/plugin-oas";
    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(),
        // Class-based clients for direct usage
        pluginClient({
          output: {
            path: "./clients/class",
          },
          clientType: "class",
          group: { type: "tag" },
        }),
        // Query hooks work with inline function-based clients
        pluginReactQuery({
          output: {
            path: "./hooks",
          },
        }),
      ],
    });

    Changes:

    • Added clientType to client option types for all query plugins
    • Query plugins automatically generate inline clients when clientType: 'class' is detected
    • Updated documentation with compatibility warnings and usage examples

4.9.0

✨ Features

  • plugin-client - Class-based client generation

    Add support for class-based client generation via the new clientType option. Users can now generate API clients as classes with methods instead of standalone functions by setting clientType: 'class' in the plugin configuration. When combined with group: { type: 'tag' }, this generates one class per tag (e.g., Pet, Store, User) with methods for each operation.

    typescript
    import { defineConfig } from "@kubb/core";
    import { pluginClient } from "@kubb/plugin-client";
    import { pluginOas } from "@kubb/plugin-oas";
    import { pluginTs } from "@kubb/plugin-ts";
    
    export default defineConfig({
      input: {
        path: "./petStore.yaml",
      },
      output: {
        path: "./src/gen",
      },
      plugins: [
        pluginOas(),
        pluginTs(),
        pluginClient({
          output: {
            path: "./clients",
          },
          clientType: "class",
          group: {
            type: "tag",
          },
        }),
      ],
    });
    typescript
    export class Pet {
      #client: typeof fetch;
    
      constructor(
        config: Partial<RequestConfig> & { client?: typeof fetch } = {},
      ) {
        this.#client = config.client || fetch;
      }
    
      async getPetById({ petId }: { petId: number }, config = {}) {
        const { client: request = this.#client, ...requestConfig } = config;
        const res = await request<
          GetPetByIdQueryResponse,
          ResponseErrorConfig<GetPetById400>,
          unknown
        >({
          method: "GET",
          url: `/pet/${petId}`,
          ...requestConfig,
        });
        return res.data;
      }
    
      async addPet(data: AddPetMutationRequest, config = {}) {
        const { client: request = this.#client, ...requestConfig } = config;
        const requestData = data;
        const res = await request<
          AddPetMutationResponse,
          ResponseErrorConfig<AddPet405>,
          AddPetMutationRequest
        >({
          method: "POST",
          url: "/pet",
          data: requestData,
          ...requestConfig,
        });
        return res.data;
      }
    }
    typescript
    import { Pet } from "./gen/clients/Pet";
    
    const petClient = new Pet();
    
    // Get a pet by ID
    const pet = await petClient.getPetById({ petId: 1 });
    
    // Add a new pet
    const newPet = await petClient.addPet({
      name: "Fluffy",
      status: "available",
    });

    Key features:

    • Generated classes use ECMAScript private field syntax (#client) for true runtime privacy
    • Full support for all existing options (parser, paramsType, dataReturnType, etc.)
    • Each tag generates a separate class file when using group: { type: 'tag' }
    • Centralized client configuration per instance

4.8.1

🐛 Bug Fixes

  • plugin-client - Fix formData generation with non-standard parser

    Fix formData generation when parser is undefined or non-standard. Previously, when using multipart/form-data endpoints without setting parser to 'client' or 'zod', the generated code would attempt to call buildFormData(requestData) with an undefined requestData variable, causing a reference error.

4.8.0

✨ Features

  • plugin-zod - Zod Mini support

    Add support for Zod Mini with the new mini option. When mini: true, generates functional syntax instead of chainable methods for better tree-shaking.

typescript
z.string().optional();
typescript
z.optional(z.string());

Configuration automatically sets version to '4' and importPath to 'zod/mini' when mini mode is enabled. Updated parser to support .check() syntax for constraints in mini mode.

typescript
z.string().check(z.minLength(5));

4.7.1

🐛 Bug Fixes

  • plugin-oas

    Fix serverIndex: 0 not resolving to servers[0].url in generated code. The condition if (serverIndex) was treating 0 as falsy, causing getBaseURL() to return undefined instead of the first server URL.

4.7.0

✨ Features

  • plugin-react-query & plugin-vue-query - Bidirectional pagination support

    Add support for nextParam and previousParam in infinite queries with nested field access. This enables independent cursor extraction for bidirectional pagination.

typescript
{
  nextParam: 'pagination.next.id',
  previousParam: 'pagination.prev.id'
}
typescript
{
  nextParam: ['pagination', 'next', 'id'],
  previousParam: ['pagination', 'prev', 'id']
}

DEPRECATED

The existing cursorParam option is deprecated but remains functional for backward compatibility.

🐛 Bug Fixes

  • plugin-oas - Fix circular type references with discriminator

    Fixed self-referential circular type references when OpenAPI schemas use allOf to extend a discriminator parent that has oneOf/anyOf referencing the children. The fix detects this pattern and skips adding redundant discriminator constraints to avoid the circular structure.

4.6.3

🐛 Bug Fixes

  • plugin-client - Fix formData with missing request schema

    Fix formData not being used in generated client when request schema is missing for multipart/form-data endpoints.

4.6.2

🐛 Bug Fixes

  • plugin-zod - Skip coercion for email, url, uuid in Zod 4

    Skip coercion for email, url, uuid with Zod 4. In Zod 4, coerce does not support z.uuid(), z.email() or z.url() and coercion does not make sense with these specific string subtypes.

typescript
// When coercion: true and version: '4' are both enabled
z.uuid();
z.email();
z.url();
typescript
// Attempted to use unsupported coercion syntax
z.coerce.uuid(); // ❌ Not supported in Zod 4

4.6.1

🐛 Bug Fixes

4.6.0

✨ Features

  • plugin-react-query - useSuspenseInfiniteQuery support

    Add support for useSuspenseInfiniteQuery hook generation with the following capabilities:

  • Generate useSuspenseInfiniteQuery hooks when both suspense and infinite options are enabled

  • Support for both cursor-based and offset-based pagination with full TypeScript type safety

  • Automatic validation of required query parameters and response fields

typescript
// Generated hook name example
useFindPetsByTagsSuspenseInfinite();
typescript
{
  suspense: true,
  infinite: true
}

4.5.15

🐛 Bug Fixes

  • plugin-client - Fix FormData handling in fetch client

    Fix FormData handling in fetch client to properly support multipart/form-data requests. FormData instances are now passed directly to the fetch API instead of being JSON.stringify-ed, allowing the browser to correctly set the Content-Type header with the multipart boundary.

typescript
fetch(url, {
  body: formData, // Passed directly
});
typescript
fetch(url, {
  body: JSON.stringify(formData), // ❌ Wrong
});

4.5.14

✨ Features

4.5.13

🐛 Bug Fixes

  • plugin-client - Fix FormData type error

    Fix TypeScript type error: Type 'FormData' is missing the following properties from type at generated hooks.

4.5.12

🐛 Bug Fixes

  • plugin-zod - Fix circular dependency with z.lazy()

    Fix circular dependency issues by wrapping all schema references in z.lazy() to prevent "used before declaration" errors with oneOf/anyOf constructs.

typescript
// All references wrapped in z.lazy()
z.lazy(() => Schema);
  • plugin-swr - Fix mutation type issue

    Fix SWR mutation type issue by using SWRMutationConfiguration directly instead of Parameters<typeof useSWRMutation>[2]. This resolves type inference issues caused by SWR's function overloading based on throwOnError, allowing flexible definition and passing of mutation configuration options.

  • plugin-vue-query - Fix undefined schema handling

    • Fixed potential runtime errors when handling undefined schemas
  • Improved queryKey extraction safety with reactive value resolution

  • core - Fix undefined schema handling

    Fixed potential runtime errors when handling undefined schemas.

✨ Features

  • unplugin-kubb - Multi-framework support

    Added multi-framework support (Vite and Rollup).

📦 Dependencies

Update development dependencies (Vite, Nuxt, Biome).

4.5.11

📦 Dependencies

Upgrade to have latest react-fabric version.

4.5.10

📦 Dependencies

Upgrade to have latest react-fabric version.

4.5.9

🐛 Bug Fixes

  • plugin-oas - Fix discriminator inherit issue

    Fix discriminator inherit issue, resolved by applying inherit on setOptions.

4.5.8

📦 Dependencies

Rebuild core packages.

4.5.7

📦 Dependencies

Rebuild core packages.

4.5.6

🐛 Bug Fixes

  • core - Correct Plugins type

    Correct type for Plugins.

4.5.3

🐛 Bug Fixes

  • plugin-oas - Expose generators helpers

    Expose generators helpers again in main barrel of plugin-oas.

4.5.2

📦 Dependencies

Update Fabric packages.

4.5.1

🐛 Bug Fixes

  • plugin-zod - Fix optional query parameters

    Fix query parameter object with all parameters defaulting incorrectly marked as optional in Zod.

4.5.0

🚀 Breaking Changes

  • Removed @kubb Dependency from Generated Files

    All query plugins now generate self-contained code with a .kubb folder containing necessary utilities:

    BENEFIT

    Generated code no longer depends on @kubb runtime packages, making the output more portable and easier to customize.

    typescript
    import { client } from "@kubb/plugin-client";
    typescript
    import { client } from "./.kubb/client";
  • plugin-zod - Remove @kubb dependency

    Removed Dependencies:

    • Remove dependency of @kubb inside the generated files
    • Introduce a .kubb folder containing the ToZod helper

    Bug Fixes:

    • Zod schema was not adding .max, revert previous changes to bring back this feature
    • Add z.lazy for every reference but when used in Zod v4 with get(){} syntax remove the z.lazy

✨ Features

  • plugin-oas - Sort schemas for correct reference order

    Sort OpenApi Schemas so references are having a correct order when generated.

4.4.1

📦 Dependencies

Update Fabric packages.

4.4.0

✨ Features

Add Fabric support for improved code generation.

4.3.1

📦 Dependencies

  • react - Update PeerDependencies

    Update PeerDependencies @kubb/react.

4.3.0

✨ Features

  • plugin-zod - Exclusive min/max constraints

    Add exclusive minimum and maximum support with Zod constraints.

typescript
z.number().gt(5); // Greater than 5
z.number().lt(10); // Less than 10

4.2.2

🐛 Bug Fixes

  • core - Fix Fabric patch version crash

    Resolve crash with incorrect Fabric patch version.

4.2.1

📦 Dependencies

Update packages.

4.2.0

✨ Features

  • plugin-msw - Generate responses for status codes

    Generating responses for status codes.

4.1.4

✨ Features

  • plugin-faker - Optional data parameter

    Add optional data parameter to override default faker generated strings and numbers.

🐛 Bug Fixes

  • plugin-client - Fix content-type header for multipart

    Correct content-type header handling for multipart/form-data.

  • plugin-zod - Add operation types

    Add type to operations generated by zod plugin.

4.1.3

✨ Features

  • plugin-msw - Promise response support

    Add promise response to msw handlers.

4.1.2

🐛 Bug Fixes

  • plugin-react-query - Guard infinite hooks

    Guard infinite hooks and streamline mutation typings.

  • core - Fix regex with flags

    Fix generation failing when using regexes that contain flags.

  • plugin-zod - URL min/max constraints

    URL should also set min and max when defined.

4.1.1

📦 Dependencies

Upgrade internal packages.

4.1.0

✨ Features

  • plugin-react-query - Add mutationOptions

    Add mutationOptions to react-query.

  • plugin-zod - z.ZodType for Zod v4

    Use of z.ZodType when using Zod v4.

4.0.2

🐛 Bug Fixes

  • plugin-zod - Escape omit keys

    Escape omit keys correctly with '.

  • plugin-client - Support stringify for multipart

    Support stringify when using multipart/form-data.

4.0.1

📦 Dependencies

Upgrade internal packages.

4.0.0

🚀 Breaking Changes

  • plugin-ts - Enum Key suffix for asConst

    Enums generated with "asConst" have a "Key" suffix.

typescript
const StatusKey = {
  Active: "active",
  Inactive: "inactive",
} as const;
typescript
const Status = {
  Active: "active",
  Inactive: "inactive",
} as const;

3.18.4

🐛 Bug Fixes

  • plugin-ts

    Keep usedEnumNames in cache but not between builds.

3.18.3

🐛 Bug Fixes

3.18.2

📦 Dependencies

  • core

    Update packages.

3.18.1

🐛 Bug Fixes

  • parser/ts

    Revert prettier removal as default formatter.

3.18.0

✨ Features

Custom Linters Support:

3.17.1

🐛 Bug Fixes

3.17.0

✨ Features

3.16.4

✨ Features

3.16.3

🐛 Bug Fixes

  • plugin-msw

    Return contentType from response instead of request.

  • plugin-faker

    Update Faker parser to work with enums in nested objects.

3.16.2

📦 Dependencies

Upgrade of internal dependencies.

3.16.1

✨ Features

🐛 Bug Fixes

  • plugin-ts

    • Fix ERROR Warning: Encountered two children with the same key
  • Fix pattern property not considered for JSDoc

3.16.0

✨ Features

  • core

    Improve memory usage by using concurrency.

3.15.0

✨ Features

  • plugin-swr

    Add immutable option to disable revalidateIfStale, revalidateOnFocus and revalidateOnReconnect.

INFO

See SWR Documentation for more details.

typescript
const { data, error } = useGetOrderById(2);
typescript
const { data, error } = useGetOrderById(2, { immutable: true });

3.14.4

🐛 Bug Fixes

  • plugin-oas

    Fix AnyOf where const (empty string) is being used should not be converted to a nullable value.

json
{
  "anyOf": [
    {
      "const": "",
      "type": "string"
    },
    {
      "format": "email",
      "type": "string"
    }
  ]
}
typescript
type Order = {
  status?: null | string;
};
typescript
type Order = {
  status?: string;
};

3.14.3

✨ Features

  • plugin-client & plugin-msw - Google API format paths

    Support Google API format paths:

    typescript
    // Google API path format
    my-api/foo/v1/bar/{id}:search

3.14.2

🐛 Bug Fixes

  • plugin-oas

    Fix required properties not handled correctly when allOf is used.

3.14.1

🐛 Bug Fixes

  • parser/ts

    • Fixed order of import and export files when using print of TypeScript
  • Fixed TypeScript version

3.14.0

✨ Features

  • cli

    New CLI Commands:

bash
# Validate a Swagger/OpenAPI file
npx kubb validate --input swagger.json
bash
# Start the MCP client to interact with LLMs (like Claude)
npx kubb mcp

3.13.2

🐛 Bug Fixes

  • plugin-client

    Fix shadowed variables error when using client, use of fetch instead when an import to @kubb/plugin-client/clients/axios is needed.

3.13.1

✨ Features

  • plugin-client

    Parse and validate request data with Zod, including FormData, before forwarding it to the client.

3.13.0

✨ Features

  • Multiple Plugins - Add emptySchemaType option

    Add emptySchemaType option across plugins. It is used whenever schema is "empty" and defaults to the value of unknownType when not specified which maintains backwards compatibility.

3.12.2

🐛 Bug Fixes

3.12.1

🐛 Bug Fixes

  • plugin-zod

    Correct v4 imports when no importPath is defined.

3.12.0

✨ Features

3.11.1

🐛 Bug Fixes

  • plugin-oas

    Resolve anyof when used together with allof.

3.11.0

✨ Features

  • plugin-oas

    Discriminator flag that could override a schema when mapping is used (see inherit), resolves #1736.

🐛 Bug Fixes

  • plugin-zod

    Enums of type "number" are parsed to integers.

  • plugin-faker

    Incompatible type used for true literal enum in query param.

3.10.16

🐛 Bug Fixes

  • plugin-ts

    ConstEnum should be treated as export _ instead of export type _.

3.10.15

🐛 Bug Fixes

  • plugin-ts

    Fix nullable response inconsistency between @kubb/plugin-ts and @kubb/plugin-zod plugins.

3.10.14

🐛 Bug Fixes

  • plugin-faker

    Fix min and max not applied to the faker functions when only one of them is defined.

  • core

    Add uniqueBy for file.sources (isExportable and name).

  • plugin-ts

    Fix duplicated enums on TypeScript types.

3.10.13

🐛 Bug Fixes

  • plugin-zod

    Query parameter objects are no longer optional if at least one parameter is defaulted.

3.10.12

✨ Features

  • plugin-oas

    Allow multiple discriminator.mapping with the same $ref.

3.10.11

📦 Dependencies

  • plugin-zod

    Update parser to include latest v4 of Zod.

3.10.10

🐛 Bug Fixes

3.10.9

📦 Dependencies

  • core

    Update packages.

3.10.8

✨ Features

3.10.7

🐛 Bug Fixes

  • core

    Better support for Windows.

3.10.6

✨ Features

3.10.5

✨ Features

🐛 Bug Fixes

3.10.4

✨ Features

3.10.3

✨ Features

3.10.2

🐛 Bug Fixes

3.10.1

📦 Dependencies

Update of internal libraries.

3.10.0

✨ Features

  • plugin-mcp

    Create an MCP server based on your OpenAPI file and interact with an AI like Claude.

Claude interaction

3.9.5

🐛 Bug Fixes

  • plugin-ts

    Fix OpenAPI description tag not put into the JSDoc.

3.9.4

🐛 Bug Fixes

  • plugin-swr

    Fix query type inferred as any when generating SWR hooks with useSWR.

3.9.3

✨ Features

  • plugin-ts

    nullable: true now generates | null union.

3.9.2

🐛 Bug Fixes

3.9.1

🐛 Bug Fixes

Reduce any's being used:

3.9.0

  • core: add default banner feature to enhance generated file recognizability by @akinoccc

3.8.1

3.8.0

  • react: Support for React 19 and expose useState, useEffect, useRef from @kubb/react

3.7.7

  • plugin-oas: support for contentType override/exclude/include

3.7.6

3.7.5

3.7.4

3.7.3

3.7.2

  • plugin-client: method should be optional for default fetch and axios client

3.7.1

3.7.0

  • plugin-cypress: support for cy.request with new plugin @kubb/plugin-cypress

3.6.5

3.6.4

  • Update external packages

3.6.3

3.6.2

  • plugin-zod: handling circular dependency properly when using ToZod helper

3.6.1

3.6.0

✨ Features

  • plugin-zod

    Adds wrapOutput option to allow for further customizing the generated zod schemas, making it possible to use OpenAPI on top of your Zod schema.

typescript
import { z } from "@hono/zod-openapi";

export const showPetByIdError = z
  .lazy(() => error)
  .openapi({
    examples: [
      {
        sample: {
          summary: "A sample error",
          value: { code: 1, message: "A sample error message" },
        },
      },
      {
        other_example: {
          summary: "Another sample error",
          value: { code: 2, message: "A totally specific message" },
        },
      },
    ],
  });
  • plugin-oas

    Discriminator mapping with literal types.

typescript
export type FooBase = {
  /**
   * @type string
   */
  $type: string;
};
typescript
export type FooBase = {
  /**
   * @type string
   */
  $type: "type-string" | "type-number";
};
typescript
export type FooNumber = FooBase {
  /**
   * @type number
   */
  value: number;
};
typescript
export type FooNumber = FooBase & {
  /**
   * @type string
   */
  $type: "type-number";

  /**
   * @type number
   */
  value: number;
};

3.5.13

3.5.12

  • core: internal packages update

3.5.11

  • core: internal packages update

3.5.10

3.5.9

3.5.8

3.5.7

  • react: Bun does not follow the same node_modules structure, to resolve this we need to include the React bundle inside of @kubb/react. This will increase the size with 4MB.

3.5.6

3.5.5

  • plugin-client: support custom client in options
  • plugin-faker: faker.number.string with default min Number.MIN_VALUE and max set to Number.MAX_VALUE

3.5.4

3.5.3

  • plugin-client: allow exporting custom client fetch function and use generated fetch when pluginClient is available
  • plugin-react-query: allow exporting custom client fetch function and use generated fetch when pluginClient is available
  • plugin-svelte-query: allow exporting custom client fetch function and use generated fetch when pluginClient is available
  • plugin-vue-query: allow exporting custom client fetch function and use generated fetch when pluginClient is available
  • plugin-solid-query: allow exporting custom client fetch function and use generated fetch when pluginClient is available
  • plugin-swr: allow exporting custom client fetch function and use generated fetch when pluginClient is available

3.5.2

  • plugin-faker: faker.number.float with default min Number.MIN_VALUE and max set to Number.MAX_VALUE.
  • plugin-oas: remove duplicated keys when using allOf and applying required on fields

3.5.1

  • core: build of @kubb/core with correct types
  • plugin-oas: allow grouping

3.5.0

  • core: support banner with context for Oas
typescript
pluginTs({
  output: {
    path: 'models',
    banner(oas) {
      return `// version: ${oas.api.info.version}`
    },
  },
}),

3.4.6

  • core: ignore acronyms when doing casing switch to pascal or camelcase

3.4.5

  • plugin-client: if client receives no body (no content) then it throws JSON parsing error
  • plugin-zod: use of as ToZod instead of satisfies ToZod

3.4.4

3.4.3

  • plugin-oas: correct use of grouping for path and tags

3.4.2

  • plugin-oas: remove duplicated keys when set in required

3.4.1

  • plugin-faker: min and max was not applied to the faker functions

3.4.0

3.3.5

3.3.4

  • plugin-ts: minLength, maxLength, pattern as part of the jsdocs
  • plugin-client: baseURL could be undefined, do not throw error if that is the case

3.3.3

  • react: Use of @kubb/react as importSource for jsx(React 17, React 18, React 19 could be used next to Kubb)
  • cli: Use of @kubb/react as importSource for jsx(React 17, React 18, React 19 could be used next to Kubb)

3.3.2

  • react: Support div and other basic elements to be returned by @kubb/react

3.3.1

  • plugin-zod: Use of tozod util to create schema based on a type

3.3.0

  • plugin-client: client to use fetch or axios as HTTP client
  • plugin-zod: Use Regular expression literal instead of RegExp-constructor
  • plugin-ts: Switch between the use of type or interface when creating types

3.2.0

3.1.0

✨ Features

typescript
group: {
  type: 'path',
  name: ({ group }) => {
    const firstSegment = group.split('/')[1];
    return firstSegment;
  }
}
typescript
findPetsByStatusHandler((info) => {
  const { params } = info;
  if (params.someKey) {
    return new Response(JSON.stringify({ error: "some error response" }), {
      status: 400,
    });
  }
  return new Response(JSON.stringify({ newData: "new data" }), { status: 200 });
});

3.0.14

  • core: Upgrade packages

3.0.13

  • core: Upgrade packages
  • plugin-oas: Applying required on fields inherited using allOf

3.0.12

3.0.11

  • core: Disabling output file extension
  • plugin-oas: Correct use of Jsdocs syntax for links
  • core: Respect casing of parameters

3.0.10

  • plugin-faker: data should have a higher priority than faker defaults generation

3.0.9

  • plugin-oas: Allow nullable with default null option
  • core: Correct use of barrelType for single files

3.0.8

  • plugin-zod: Blob as z.instanceof(File) instead of string

3.0.7

  • core: Include single file exports in the main index.ts file.

3.0.6

  • plugin-oas: Correct use of variables when a path/params contains _ or -
  • core: barrelType: 'propagate' to make sure the core can still generate barrel files, even if the plugin will not have barrel files

3.0.5

  • react: Better error logging + wider range for @kubb/react peerDependency

3.0.4

  • Upgrade external dependencies

3.0.3

3.0.2

3.0.1

3.0.0-beta.12

  • plugin-react-query: allow to disable the generation of useQuery or createQuery hooks.
  • plugin-svelte-query: allow to disable the generation of useQuery or createQuery hooks.
  • plugin-vue-query: allow to disable the generation of useQuery or createQuery hooks.
  • plugin-solid-query: allow to disable the generation of useQuery or createQuery hooks.
  • plugin-swr: allow to disable the generation of useQuery or createQuery hooks.

3.0.0-beta.11

  • plugin-ts: enumType 'enum' without export type in barrel files
  • plugin-client: Allows you to set a custom base url for all generated calls

3.0.0-beta.10

  • plugin-react-query: paramsType with options 'inline' and 'object' to have control over the amount of parameters when calling one of the generated functions.
  • plugin-svelte-query: paramsType with options 'inline' and 'object' to have control over the amount of parameters when calling one of the generated functions.
  • plugin-vue-query: paramsType with options 'inline' and 'object' to have control over the amount of parameters when calling one of the generated functions.
  • plugin-solid-query: paramsType with options 'inline' and 'object' to have control over the amount of parameters when calling one of the generated functions.
  • plugin-client: paramsType with options 'inline' and 'object' to have control over the amount of parameters when calling one of the generated functions.

3.0.0-beta.9

  • plugin-msw: parser option to disable faker generation
    • 'faker' will use @kubb/plugin-faker to generate the data for the response
    • 'data' will use your custom data to generate the data for the response
  • plugin-msw: Siblings for better AST manipulation

3.0.0-beta.8

3.0.0-beta.7

  • Upgrade external packages

3.0.0-beta.6

  • plugin-faker: Min/Max for type array to generate better faker.helpers.arrayElements functionality

3.0.0-beta.5

  • plugin-zod: Discard optional() if there is a default() to ensure the output type is not T | undefined

3.0.0-beta.4

  • Upgrade external packages

3.0.0-beta.3

  • plugin-zod: Added coercion for specific types only
typescript
type coercion =
  | boolean
  | { dates?: boolean; strings?: boolean; numbers?: boolean };

3.0.0-beta.2

  • Upgrade external packages

3.0.0-beta.1

  • Upgrade external packages

3.0.0-alpha.31

  • plugin-client: Generate ${tag}Service controller file related to group x when using group(no need to specify group.exportAs)
  • plugin-core: Removal of group.exportAs
  • plugin-core: Removal of group.output in favour of group.name(no need to specify the output/root)
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",
    clean: true,
  },
  plugins: [
    pluginOas({ generators: [] }),
    pluginClient({
      output: {
        path: "./clients/axios",
      },
      // group: { type: 'tag', output: './clients/axios/{{tag}}Service' },
      group: { type: "tag", name: ({ group }) => `${group}Service` },
    }),
  ],
});

3.0.0-alpha.30

  • plugin-core: Removal of output.extName in favour of output.extension
  • plugin-core: Removal of exportType in favour of barrelType

3.0.0-alpha.29

3.0.0-alpha.28

3.0.0-alpha.27

  • plugin-swr: Support for TypeScript strict mode
  • plugin-react-query: Support for TypeScript strict mode and use of data object for mutationFn: async(data: {})
  • plugin-svelte-query: Support for TypeScript strict mode and use of data object for mutationFn: async(data: {})
  • plugin-vue-query: Support for TypeScript strict mode and use of data object for mutationFn: async(data: {})
  • plugin-solid-query: Support for TypeScript strict mode and use of data object for mutationFn: async(data: {})

3.0.0-alpha.26

  • plugin-swr: Expose queryKey and mutationKey for the SWR plugin
  • 'generators' option for all plugins

3.0.0-alpha.25

3.0.0-alpha.24

3.0.0-alpha.23

  • plugin-client: Use of uppercase for httpMethods, GET instead of get, POST instead of post, ...

3.0.0-alpha.22

  • plugin-faker: Use of faker.image.url() instead of faker.image.imageUrl()
  • plugin-zod: Enums should use z.literal when format is set to number, string or boolean
yaml
enum:
  type: boolean
  enum:
    - true
    - false
typescript
z.enum(["true", "false"]);
z.union([z.literal(true), z.literal(false)]);
  • plugin-ts: Use of readonly for references($ref)
  • plugin-client: Use of type Error when no errors are set for an operation

3.0.0-alpha.21

  • plugin-zod: Use of x-nullable and nullable for additionalProperties.

3.0.0-alpha.20

  • Separate plugin/package for Solid-Query: @kubb/plugin-solid-query
kubb.config.ts
typescript
import { defineConfig } from "@kubb/core";
import { pluginOas } from "@kubb/plugin-oas";
import { pluginTs } from "@kubb/plugin-ts";
import { pluginSolidQuery } from "@kubb/plugin-solid-query";
import { pluginTanstackQuery } from "@kubb/plugin-tanstack-query";

export default defineConfig({
  root: ".",
  input: {
    path: "./petStore.yaml",
  },
  output: {
    path: "./src/gen",
    clean: true,
  },
  plugins: [
    pluginOas({ generators: [] }),
    pluginTs({
      output: {
        path: "models",
      },
    }),
    pluginSolidQuery({
      output: {
        path: "./hooks",
      },
    }),
  ],
});
  • Separate plugin/package for Svelte-Query: @kubb/plugin-svelte-query
kubb.config.ts
typescript
import { defineConfig } from "@kubb/core";
import { pluginOas } from "@kubb/plugin-oas";
import { pluginTs } from "@kubb/plugin-ts";
import { pluginSvelteQuery } from "@kubb/plugin-svelte-query";
import { pluginTanstackQuery } from "@kubb/plugin-tanstack-query";

export default defineConfig({
  root: ".",
  input: {
    path: "./petStore.yaml",
  },
  output: {
    path: "./src/gen",
    clean: true,
  },
  plugins: [
    pluginOas({ generators: [] }),
    pluginTs({
      output: {
        path: "models",
      },
    }),
    pluginSvelteQuery({
      output: {
        path: "./hooks",
      },
    }),
  ],
});
  • Separate plugin/package for Vue-Query: @kubb/plugin-vue-query
kubb.config.ts
typescript
import { defineConfig } from "@kubb/core";
import { pluginOas } from "@kubb/plugin-oas";
import { pluginTs } from "@kubb/plugin-ts";
import { pluginVueQuery } from "@kubb/plugin-vue-query";
import { pluginTanstackQuery } from "@kubb/plugin-tanstack-query";

export default defineConfig({
  root: ".",
  input: {
    path: "./petStore.yaml",
  },
  output: {
    path: "./src/gen",
    clean: true,
  },
  plugins: [
    pluginOas({ generators: [] }),
    pluginTs({
      output: {
        path: "models",
      },
    }),
    pluginVueQuery({
      output: {
        path: "./hooks",
      },
    }),
  ],
});

3.0.0-alpha.16

  • Separate plugin/package for React-Query: @kubb/plugin-react-query
kubb.config.ts
typescript
import { defineConfig } from "@kubb/core";
import { pluginOas } from "@kubb/plugin-oas";
import { pluginTs } from "@kubb/plugin-ts";
import { pluginReactQuery } from "@kubb/plugin-react-query";
import { pluginTanstackQuery } from "@kubb/plugin-tanstack-query";

export default defineConfig({
  root: ".",
  input: {
    path: "./petStore.yaml",
  },
  output: {
    path: "./src/gen",
    clean: true,
  },
  plugins: [
    pluginOas({ generators: [] }),
    pluginTs({
      output: {
        path: "models",
      },
    }),
    pluginReactQuery({
      output: {
        path: "./hooks",
      },
    }),
  ],
});

Released under the MIT License.