Skip to content

Changelog

v5.0.0-beta.42 — Jun 5, 2026

@kubb/core

Features

  • Add an opt-in incremental build cache.

    Kubb now fingerprints the inputs that shape generated code (the spec content, the resolved config, every plugin's options, and the running version) and, when nothing changed, restores the previous output instead of regenerating it. A second run becomes near-instant, the same idea behind Nx's computation cache.

    defineConfig turns this on by default with fsCache() (local disk under node_modules/.cache/kubb). Set cache: false to turn it off, or pass another backend through the new cache option, which mirrors the existing storage option. @kubb/core ships the fsCache() backend, plus the Cache type and createCache factory for custom ones. A bare createKubb leaves caching off unless a cache is passed.

    ts
    import { defineConfig } from 'kubb'
    
    export default defineConfig({
      input: { path: './petStore.yaml' },
      output: { path: './src/gen' },
      // cache: fsCache() is applied by default; set `cache: false` to turn it off.
    })
    ``` ([#3469](https://github.com/kubb-labs/kubb/pull/3469), [`eeab54b`](https://github.com/kubb-labs/kubb/commit/eeab54b2823a5e591c9ec2b05cb31abf32f37cb2))
  • Run Kubb natively on Bun while keeping full Node support.

    Runtime detection is now centralized, so the filesystem helpers reach for Bun.file and Bun.write under Bun and fall back to node:fs everywhere else. The default fsStorage scans the output directory with Bun.Glob under Bun instead of a recursive readdir walk. The kubb agent command launches its server with the same runtime that started the CLI (via process.execPath) instead of always shelling out to node, so a Bun-only environment no longer needs a node binary on the PATH. Anonymous telemetry also records which runtime ran the generation (bun, deno, or node) alongside its version. (#3470, 1ca92f6)

Bug Fixes

  • Adopt native Node 22 / ES2024 features: order plugins through Set-based dependency lookups in KubbDriver, and replace Promise resolver boilerplate with Promise.withResolvers(). The shared TypeScript config moves to an ES2024 target with the ES2025 collection and iterator libraries to match the Node 22 baseline. (#3473, 50615f4)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.41 — Jun 3, 2026

@kubb/cli

Bug Fixes

  • Remove the GitHub Actions logger. The CLI now picks the clack or plain logger based on whether a TTY is available, regardless of the CI environment. (#3463, 7798632)

@kubb/core

Features

  • Route hook subprocess output through events instead of a sink-factory callback.

    Hook output (formatter, linter, and done hooks) now reaches loggers over the event emitter: a new kubb:hook:line event carries each streamed stdout line while a hook runs, and kubb:hook:end gained optional stdout/stderr fields holding a failed hook's captured output. The CLI's makeSink/HookSinkFactory channel and its threading are removed, so loggers are pure event subscribers and the runner decides whether to stream from the kubb:hook:line listener count. Behavior is unchanged: clack still streams live dimmed lines, the plain logger still prints failure output, and a failed hook's output still surfaces at the silent log level. (#3467, 333aea7)

Bug Fixes

  • Restore progressive Plugins N/M progress in the CLI. The driver now runs each plugin's generator pass sequentially, so kubb:plugin:end fires as each plugin finishes instead of once the whole batch pass is over. The CLI counter advances 2/9, 3/9, ..., 9/9 again rather than jumping from 1/9 straight to 9/9 at the end of the run. (#3465, be22e6d)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.40 — Jun 3, 2026

@kubb/core

Bug Fixes

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.39 — Jun 3, 2026

@kubb/core

Features

  • Fold the diagnostic error helpers into the Diagnostics namespace: DiagnosticError is now Diagnostics.Error and the structural check is exposed as Diagnostics.isError.

    The standalone DiagnosticError export from @kubb/core is removed. Replace new DiagnosticError(...) with new Diagnostics.Error(...), and import Diagnostics instead. The thrown error keeps its name of 'DiagnosticError', so structural checks across duplicated @kubb/core copies still match. (#3458, ec9a92c)

  • Remove the public FileProcessor export from @kubb/core and move the matchFiles snapshot helper into @kubb/core/mocks. matchFiles(files, { parsers, format, pre }) takes its parsers and formatter as options, so it renders generator output to file snapshots without @kubb/core pulling in a parser or prettier. (#3458, 1b19a0c)

  • Remove the exported isInputPath type guard from @kubb/core. It had a single internal caller, where the check is now an inline 'path' in config.input that narrows the InputPath | InputData union on its own. (#3458, ec69a5c)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.38 — Jun 3, 2026

@kubb/core

Bug Fixes

  • Fix diagnostic reporting regressions found in review.

    • resolveRef now throws a DiagnosticError when a $ref cannot be resolved outside a build scope, instead of silently returning null. Inside a build it still collects the diagnostic and keeps parsing.
    • Plugin-reported problems (ctx.error/ctx.warn/ctx.info) and formatter/linter/done-hook failures no longer render twice. The generator context only collects diagnostics now, and the host renders each once after the build.
    • schemaDiagnostics builds correct RFC 6901 pointers: property names are escaped (~~0, /~1), and tuple items and oneOf/anyOf/allOf members are indexed, so distinct advisory diagnostics are no longer dropped by the dedupe.
    • kubb generate --reporter json emits one top-level JSON array for the whole run (aggregated on kubb:lifecycle:end), so multi-config runs stay valid JSON.
    • config.reporters from kubb.config.ts is honored again: --reporter no longer defaults to cli, so it only overrides the config when passed.
    • The agent forwards diagnostics, status, hrStart, and filesCreated on kubb:generation:end, so the generation summary reaches connected clients again.
    • The OAS adapter caches its parsed document, schemas, and prescan per source and per document instead of once per instance. Reusing one adapterOas() instance across a defineConfig array (configs that spread a shared baseConfig) now parses each config's spec instead of replaying the first, so every config generates its own files and reports its own file count. (50d5f1e)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.37 — Jun 3, 2026

@kubb/adapter-oas

Features

  • Give every error a stable code, and hand structured diagnostics to the MCP tools.

    Failures that used to throw a plain Error now throw a DiagnosticError with a code, a config location, and a help line: a missing input.path reports KUBB_INPUT_NOT_FOUND (the OAS adapter checks the file before reading it), an adapter configured without input reports KUBB_INPUT_REQUIRED, and merging an empty set of OAS documents reports KUBB_INPUT_REQUIRED. They surface in the run summary and --reporter json instead of as an opaque KUBB_UNKNOWN. Diagnostics.from now recognizes a DiagnosticError structurally, so a code still survives when the error crosses a duplicated @kubb/core copy bundled into an adapter or plugin.

    @kubb/core exposes Diagnostics.docsUrl(code) and Diagnostics.serialize(diagnostic), the JSON-safe shape (now including a docsUrl) shared by the JSON reporter and the MCP tools.

    The MCP generate and validate tools now return structured diagnostics, each with its code, source pointer, help, and docs link, as a readable block plus a JSON payload, so an assistant can act on the exact problem rather than parsing a message string.

    @kubb/adapter-oas gains an opt-in diagnostics option that reports two advisory diagnostics against their JSON pointers as it parses: KUBB_UNSUPPORTED_FORMAT (a warning when a schema's format falls back to the base type) and KUBB_DEPRECATED (info for a schema marked deprecated). The checks reuse the nodes the parser already produces, so they add no extra traversal of the document. Both default to off, so existing output is unchanged unless you set adapterOas({ diagnostics: { unsupportedFormat: true, deprecated: true } }). (#3449, b4f1e18)

  • Extend diagnostics so more failures are coded and visible.

    Coded errors that used to surface as KUBB_UNKNOWN: a missing Studio adapter (KUBB_ADAPTER_REQUIRED), a non-object devtools config (KUBB_DEVTOOLS_INVALID), and a resolved path escaping the output directory (KUBB_PATH_TRAVERSAL). The OAS adapter checks the input file before reading it in both generation and validate, so a missing spec reports KUBB_INPUT_NOT_FOUND (the MCP validate tool returns the coded diagnostic too).

    The formatter, linter, and post-generate hooks now report failures as diagnostics (KUBB_FORMAT_FAILED, KUBB_LINT_FAILED, KUBB_HOOK_FAILED). They appear in the run summary and kubb generate --reporter json, and a failure marks the run as failed instead of being swallowed.

    @kubb/core adds diagnosticCatalog (a title, cause, and fix for every code) and Diagnostics.explain(code), the source the kubb.dev diagnostics pages mirror. (#3449, b4f1e18)

  • Replace the debug logger with selectable reporters.

    The kubb:debug hook, the createDebugger helper, the debug log level, and the --debug flag are gone. To write a log file you now pick the file reporter.

    Reporters work like Vitest. List them on the CLI with --reporter (comma separated, for example --reporter cli,file) or in the config with reporters: ['cli', 'file'], where the CLI flag overrides the config. Three are built in: cli writes the end-of-run summary to the terminal and is the default, json writes a machine-readable report to stdout for CI, and file writes a log to .kubb/<name>-<timestamp>.log. The --reporter human name and the --report <file> flag are removed, so use --reporter json for CI output.

    The OAS adapter's advisory diagnostics (KUBB_UNSUPPORTED_FORMAT and KUBB_DEPRECATED) always run now. The adapterOas({ diagnostics }) option that gated them is removed.

    The kubb:generation:summary hook is removed. The end-of-run summary the cli reporter prints is now built from the run's diagnostics, carried on kubb:generation:end (which gains optional diagnostics, status, hrStart, and filesCreated fields). (#3449, b4f1e18)

@kubb/cli

Bug Fixes

  • Fix the clack logger rendering plugins side by side during generation.

    Plugins run concurrently, but the logger started a separate clack.progress() bar per plugin. clack renders one progress UI per line, so the bars collided onto a single line, printed blank gutter rows, and piled up keypress listeners until Node warned about an EventEmitter leak. The plugin phase now shares one progress bar that lists the plugins currently generating and advances as each finishes. The kubb:info line also no longer prints a trailing space when no extra info is attached. (#3449, b4f1e18)

@kubb/core

Features

  • Add a structured diagnostics model.

    Build failures are collected as structured Diagnostics instead of raw errors. Each has a stable code, a severity, an optional source location (a JSON pointer), and the plugin that produced it. BuildOutput now exposes a single diagnostics array (the former error, failedPlugins, and pluginTimings fields are gone), and the build emits each problem on the new kubb:diagnostic hook. Per-plugin timings are carried as timing diagnostics in the same array. @kubb/core exports hasBuildError and getFailedPluginNames to read them. Three throw sites carry codes: KUBB_REF_NOT_FOUND, KUBB_INVALID_SERVER_VARIABLE, and KUBB_PLUGIN_NOT_FOUND. (#3449, b4f1e18)

  • Round out diagnostic reporting toward tsc/oxlint/nx parity.

    Report without throwing. The diagnostics helpers are now a Diagnostics class. Diagnostics.report(diagnostic) collects into the active run instead of aborting, available on the generator context and, via a single AsyncLocalStorage in the core bundle, to deep code (adapter parse, lazily consumed streams). Diagnostics.scope activates a run, and Diagnostics.dedupe collapses repeats by code + pointer + plugin. (Diagnostics.from/timing/hasError/failedPlugins/count replace the former standalone functions.)

    Report every problem in one run. The OAS adapter now reports each unresolved $ref and keeps parsing, so a spec with several bad refs surfaces them all in a single kubb generate (it still throws when called outside a build).

    Aggregate count. The end-of-run summary box gains an Issues: N errors, M warnings row, so parse-time errors that aren't tied to a failed plugin still show.

    Machine-readable output. kubb generate --reporter json prints a stable report ({ status, summary: { errors, warnings, files, durationMs }, diagnostics }) to stdout. Exit code is unchanged (non-zero on any error).

    New codes KUBB_UNSUPPORTED_FORMAT (warning) and KUBB_DEPRECATED (info) are emitted by the OAS adapter. The renderer, counts, and json report handle every severity. (#3449, b4f1e18)

  • Render build diagnostics in the oxlint style and add a suggested fix.

    Diagnostic gains a help field with a suggested fix. The three converted throw sites set it, and the CLI renders a diagnostic as:

    × @kubb/plugin-zod(KUBB_REF_NOT_FOUND): Could not find a definition for Pet.
      at #/components/schemas/Pet
      help: Add the schema under components.schemas, or fix the $ref.
      docs: https://kubb.dev/docs/5.x/reference/diagnostics/kubb-ref-not-found

    The docs: link is derived from the code and points at the diagnostics reference on kubb.dev. A failed run also prints an Environment: row (Node version, Kubb version, platform, cwd) in the summary box. getDiagnosticInfo is exported from @kubb/core. (#3449, b4f1e18)

  • Resolve the renderer from the generator only. The renderer resolution chain dropped the plugin and config fallbacks, so generator.renderer is now the single source.

    Removed the renderer option from defineConfig, the renderer field from the normalized plugin, and the setRenderer method from the plugin setup context. Set renderer on each generator instead (renderer: jsxRenderer), or leave it unset / renderer: null to opt out of rendering. (#3447, 61ca887)

  • Route the generator context's warn/error/info through the diagnostics layer so plugin-reported problems are collected like every other diagnostic.

    Until now these methods only emitted kubb:warn/kubb:error/kubb:info events, so a plugin calling ctx.error(...) logged a line but the build still succeeded, and the message never reached the run summary or --reporter json. They now report into the active run via Diagnostics.report (attributed to the plugin) while still emitting their hook event:

    • ctx.error reports an error diagnostic (KUBB_PLUGIN_FAILED), which now fails the build. When passed an Error, it is kept as the diagnostic cause.
    • ctx.warn reports a warning (KUBB_PLUGIN_WARNING), and ctx.info reports an info (KUBB_PLUGIN_INFO). Neither fails the build.

    For a structured diagnostic with a stable code and a source location, call Diagnostics.report(...) or throw a DiagnosticError directly. The Diagnostic, DiagnosticSeverity, DiagnosticLocation, and DiagnosticKind types are now exported so you can build one. (#3449, b4f1e18)

  • Collapse the driver's two listener trackers (#hookListeners and #middlewareListeners) into one typed HookRegistry that wraps AsyncEventEmitter. Listeners attached directly via kubb.hooks.on(...) survive dispose(). Only listeners the driver itself registered are removed. Internal refactor: every (...args: Array<never>) cast inside KubbDriver is gone, and the public definePlugin, KubbHooks, and kubb.hooks surfaces are unchanged. (#3445, bd7e026)

Bug Fixes

  • Lift the per-plugin transform step into a Transform registry that the driver consults during dispatch, so transforms have one home and one contract instead of being inlined in KubbDriver.#runGenerators. The driver keeps the parse and generate logic as private methods (#parseInput, #runGenerators) and exposes the renderer-or-file dispatch as a KubbDriver.applyResult static so both the registered generators and @kubb/core/mocks route through one entry point.

    Bug fix: gen.operations(nodes, ctx) and the kubb:generate:operations hook now receive the transformed nodes, matching what gen.operation(node, ctx) already received per-node. Before this fix the aggregated callback saw the original adapter nodes, so a renaming-transformer would feed grouped or barrel generators a different shape than the per-operation hook saw.

    The flush-after-batch logic that used to live as a closure inside KubbDriver.run moved into a new FileWriteQueue class. The class also makes the flush non-blocking: the next round of generator dispatch can run while the previous round's source rendering and storage writes are still in flight. For large specs (Stripe-sized OpenAPI documents, thousands of generated files) the pipelined flush keeps peak heap roughly the same and lets CPU work overlap with IO instead of running behind it.

    The public surface (setTransformer, KubbHooks, the KubbDriver class, the @kubb/core/mocks entry) is unchanged. (#3447, 61ca887)

  • Stop the hooks emitter from tripping Node's EventEmitter leak warning.

    Each generator a plugin registers adds a listener to the shared kubb:generate:* events, so a config with several multi-generator plugins pushed past the emitter's hardcoded ceiling of 10 and printed MaxListenersExceededWarning: 11 kubb:generate:operation listeners added. Kubb.setup() now sizes the ceiling to the plugin count (max(10, plugins.length * 4)), which keeps leak detection for genuine runaway listeners while leaving room for the generators a normal plugin set registers. (#3449, b4f1e18)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.36 — Jun 1, 2026

@kubb/cli

Bug Fixes

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.35 — May 30, 2026

@kubb/core

Bug Fixes

  • Tighten internal type safety by removing any and unnecessary casts. The Parser type now defaults TMeta to object instead of any, getContext returns an honest Omit<GeneratorContext, 'options'> rather than laundering a missing field through as unknown as, and a couple of as never casts are replaced with proper optional types. No runtime behavior or public API change. (#3420, e74cb57)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.34 — May 29, 2026

@kubb/ast

Features

  • Export the isInputNode and isOutputNode type guards from the @kubb/ast entry point. Both guards were defined and documented in guards.ts but missing from the barrel, so they could not be imported alongside isOperationNode and isSchemaNode. (#3416, e3dd3c6)

kubb

Bug Fixes

  • Add a Kubb Claude Code plugin and marketplace. It brings Kubb, a meta framework for code generation, into Claude Code so you can turn an OpenAPI spec into TypeScript types, Zod schemas, Axios clients, React Query hooks and more. The plugin ships /kubb:init, /kubb:generate and /kubb:validate commands that run the kubb CLI, a config skill and a kubb-expert agent, and the @kubb/mcp server (kubb mcp) for conversational generation. Add kubb-labs/kubb as a plugin marketplace to install it. (#3411, 31ad94f)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.33 — May 29, 2026

@kubb/ast

Breaking Changes

  • Trim the @kubb/ast public API to shrink the maintained surface.

    Removed exports that were unused across both the core monorepo and the plugins, and that duplicated or backed a public counterpart:

    • Deleted (dead code): nodeKinds and mediaTypes constants (no references anywhere), the RefMap type, and the InferSchema type alias (use InferSchemaNode).
    • No longer exported (now internal):
      • collectLazy — use the eager collect
      • createContent / createRequestBody — content is normalized for you by createResponse / createOperation
      • mergeAdjacentObjects — use mergeAdjacentObjectsLazy ([...mergeAdjacentObjectsLazy(members)])
      • isSchemaEqual — compare schemaSignature(a) === schemaSignature(b)
      • isScalarPrimitive, resolveRefName, collectReferencedSchemaNames, isInputNode, isOutputNode

    The README's Refs example also referenced helpers that never existed (buildRefMap, resolveRef); it now documents the real extractRefName. (#3402, ecbde80)

Bug Fixes

  • Ship the documented @kubb/ast/types subpath and make walk() traverse concurrently.

    @kubb/ast/types is now a real export, so the README's import type { Node } from '@kubb/ast/types' resolves instead of failing — consumers can pull in node interfaces and visitor types without loading any runtime.

    walk() now visits sibling nodes concurrently up to its concurrency limit. Previously each child was awaited one at a time, so the documented concurrency option had no effect and async visitor callbacks always ran serially. (#3402, 09563b4)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.32 — May 28, 2026

@kubb/adapter-oas

Bug Fixes

  • Remove internal dead code flagged by knip in production mode. No public API changes — every removed symbol was unexported (not part of any package's exports) and unused across the workspace and the plugins repo.

    • @kubb/adapter-oas: drop the orphaned applyDiscriminatorInheritance and getMediaType helpers (the streaming path already uses buildDiscriminatorChildMap/patchDiscriminatorNode directly).
    • @kubb/core: drop the unused decodeAst devtools helper.
    • @kubb/ast: drop the unused buildRefMap, resolveRef, refMapToObject helpers and the unused node guards (isPropertyNode, isParameterNode, isResponseNode, isFunctionParameterNode, isParameterGroupNode, isFunctionParametersNode). The public RefMap type and extractRefName are kept. (#3401, e515a1c)

@kubb/ast

Bug Fixes

  • Performance: persist schema signatures in a process-wide WeakMap

    signatureOf now memoizes node → digest in a module-level WeakMap keyed by node identity, instead of a fresh Map per schemaSignature/buildDedupePlan/applyDedupe call. During streaming, each top-level schema tree was hashed twice — once by schemaSignature and again by applyDedupe — so a node is no longer re-hashed once it has been seen. Entries are released when the node is garbage-collected, and reuse is sound because signatures depend only on a node's (immutable) content. (#3396, 830896b)

  • refactor(ast): replace describeShape switch with SHAPE_KEYS registry

    Internal refactor only — no public API changes. Replaces the 12-case switch statement in describeShape with a declarative SHAPE_KEYS registry (same pattern as VISITOR_KEYS in visitor.ts). Output is byte-for-byte identical. (#3392, 3fe64a8)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.31 — May 26, 2026

@kubb/adapter-oas

Features

  • Add a dedupe option to adapterOas that collapses structurally identical schemas and enums into a single shared definition.

    OpenAPI specs frequently repeat the same shape — most often an inline enum (e.g. ['active', 'inactive']) duplicated across many properties, or an identical object reused across schemas and operations. Each unique shape is now emitted once: duplicated inline shapes are hoisted into a named schema, and every other occurrence — including a structurally identical top-level component — becomes a ref to it. Equality is shape-only, so differences in documentation such as description or example do not block deduplication. Deduplication is enabled by default; set adapterOas({ dedupe: false }) to keep every occurrence inline and reproduce the previous output.

    @kubb/ast gains the spec-agnostic primitives that power this: schemaSignature (a content hash of a schema's shape), isSchemaEqual, buildDedupePlan, and applyDedupe. (#3387, 0ee883f)

Bug Fixes

  • Treat an enum whose only value is null (drf-spectacular's NullEnum, { enum: [null] }) as a null schema instead of an empty enum.

    Previously the null value was stripped, leaving an enum with no values that rendered as never (@kubb/plugin-ts) or an invalid z.enum([]) (@kubb/plugin-zod), silently dropping nullability. The common drf-spectacular oneOf: [StatusEnum, BlankEnum, NullEnum] pattern now generates valid output (e.g. Status | "" | null). (#3384, cf72a72)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.30 — May 25, 2026

@kubb/adapter-oas

Bug Fixes

  • Isolate the OpenAPI-specific schema decisions (nullability, $ref detection and resolution, discriminator, binary) behind a single SchemaDialect passed into createSchemaParser. The converter pipeline and dispatch rules are now dialect-driven with the OAS dialect as the default, so the spec-specific surface lives in one documented place — the seam a future adapter (e.g. AsyncAPI) targets. No change to generated output. (#3377, 287a42a)

@kubb/ast

Features

  • Add a generic dispatch helper and DispatchRule type to @kubb/ast: an ordered match/convert table that maps source-spec shapes onto Kubb AST nodes. @kubb/adapter-oas now builds its OAS schema parser on top of it, replacing the long parseSchema if/else chain with a declarative schemaRules table. The mechanism is spec-agnostic, so future adapters (e.g. AsyncAPI) can reuse the same traversal by defining their own context type and rules. No change to generated output. (#3377, f657504)

  • Promote the schema dialect to @kubb/ast as a first-class, spec-agnostic contract: add a generic, guard-preserving SchemaDialect<TSchema, TRef, TDiscriminated, TDocument> type and a defineSchemaDialect helper, alongside dispatch. @kubb/adapter-oas now builds oasDialect with ast.defineSchemaDialect, so the JSON-Schema-family seam (nullability, $ref, discriminator, binary, ref resolution) is shared across adapters — an AsyncAPI adapter supplies its own dialect and reuses the converter pipeline and dispatch rules. No change to generated output. (#3377, 829a8ef)

  • Make the AST node vocabulary spec-neutral so adapters for non-OpenAPI specs (AsyncAPI, GraphQL, Prisma, Arazzo) map onto built-in nodes — the model stays closed and fully typed, no adapter-defined kinds.

    • OperationNode is now a discriminated union keyed on protocol. HttpOperationNode (protocol: 'http') guarantees non-nullable method and path; GenericOperationNode omits them for non-HTTP transports. New exports: HttpOperationNode, GenericOperationNode, OperationNodeBase, and the isHttpOperationNode guard.
    • createOperation is overloaded: passing method + path returns an HttpOperationNode and auto-sets protocol: 'http'; otherwise it returns a GenericOperationNode. @kubb/adapter-oas sets protocol: 'http', so OpenAPI output is unchanged.

    Breaking (types): read method/path only after narrowing with isHttpOperationNode(node) or node.protocol === 'http'. createOperation({ protocol: 'http' }) without method/path is no longer valid — provide both, or omit all three for a generic operation. (#3380, d06344b)

  • Adopt a Babel-style traversal architecture in @kubb/ast, keeping the node model uniform and minimal.

    • Request-body and response content entries are now first-class nodes (ContentNode), and the request body is a RequestBodyNode, so every child slot in the tree is a node rather than an anonymous wrapper object.
    • A single VISITOR_KEYS-style child-field registry now drives both walk/collect traversal and the immutable transform, replacing the per-kind hand-written tree-shape logic that previously lived in two places.
    • Adds builders createContent and createRequestBody; createOperation/createResponse apply them automatically, so adapters and existing call sites need no changes.

    Note: a schema reached through a request/response body now reports its parent as the enclosing ContentNode (previously the OperationNode/ResponseNode). (#3375, c5f5227)

  • transform now preserves identity (structural sharing): when a pass leaves a node and all its descendants unchanged it returns the same reference instead of reallocating the subtree. No-op rewrites become free and callers can detect "nothing changed" by reference, which keeps caches valid and cuts allocations on large specs. Adds an update(node, changes) factory — an identity-preserving shallow update, the analogue of the TypeScript compiler's factory.updateX. (#3377, 29b83a8)

Bug Fixes

  • Reduce internal complexity in the AST, core, and CLI packages to make them easier to work with and debug. No public API or generated output changes.

    • @kubb/ast: walk, transform, and collectLazy now share a single node-kind dispatch helper instead of three duplicated switch statements, and combineExports/combineImports share a name-merge helper.
    • @kubb/core: the schema and operation generator passes in KubbDriver are unified into one dispatch function.
    • @kubb/cli: the clack, GitHub Actions, and plain loggers share progress-counter and hook-timing helpers. (#3375, de7a15c)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.29 — May 23, 2026

@kubb/ast

Features

  • Add multiple response content type support to the AST and OpenAPI parser.

    ResponseNode now mirrors requestBody: the response body schemas live exclusively inside a content array (one entry per content type), instead of a single root-level schema/mediaType. This removes the duplicated schema that previously sat both on the node root and inside content. The OpenAPI parser populates every content type declared for a status code; body-less responses keep a single content entry whose schema is the empty/void placeholder. When the adapter contentType option is set, only that content type is kept.

    For convenience createResponse still accepts a single schema (with optional mediaType), normalizing it into one content entry, so existing callers keep working. (#3373, d70b887)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.28 — May 23, 2026

@kubb/ast

Bug Fixes

  • Keep a default import when a used named import from the same module path is retained.

    Previously, when operations were grouped into a single file, a used default import (such as a generated client runtime) could be dropped during the merge because its binding was not found in the reconstructed source string, producing references to an undefined value. combineImports now retains a default import whenever a used named/type import from the same path survives. (#3367, a15e7f7)

@kubb/core

Features

  • Give output.banner/output.footer per-file context so a directive like 'use server' can be skipped on re-export files.

    A banner/footer function now receives a BannerMeta — the document InputMeta extended with the file it is rendered into: filePath, baseName, isBarrel (an index.ts barrel), and isAggregation (a group [dir]/[dir].ts file). Existing (meta) => ... functions keep working since BannerMeta extends InputMeta.

    ts
    pluginClient({
      output: {
        banner: (meta) => (meta.isBarrel || meta.isAggregation ? '' : "'use server'"),
      },
    })

    Barrel index.ts files are now also banner-controllable: when a plugin configures output.banner/footer, the barrel middleware applies it (flagged isBarrel: true). Barrels stay banner-free by default and never inherit the implicit "Generated by Kubb" notice. (#3371, 699f924)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.27 — May 23, 2026

@kubb/adapter-oas

Bug Fixes

    • parseSchema now propagates the parent name through every call site that previously dropped it: array items (convertArray), allOf members (single, multi, and synthetic required-key + outer-properties), oneOf / anyOf member schemas, union members, operation responses ({operationId}Status{statusCode}), request bodies ({operationId}Request), and parameters ({operationId}{ParamName}).
    • Operation response schemas now use Status<code> (matching plugin-ts's resolveResponseStatusName convention) so qualified enum names don't collide with top-level component schemas named <operation><statusCode> (e.g. GetMaintenance200).
    • Two test expectations updated to reflect the new contracts:
      • Parameter top-level enums now carry a parser-level name (qualified with operation + param name) so plugin-generated downstream identifiers stay collision-free.
      • The synthetic injected-required-key member inside an allOf is now named so its nested enums qualify correctly; it consequently shows up as a separate intersection member instead of being adjacent-merged. (#3363, 2cb22fe)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.26 — May 22, 2026

@kubb/adapter-oas

Bug Fixes

  • Enforce Array<T> syntax (over T[]) via the oxlint typescript/array-type rule. Internal-only change; no runtime or API impact. (#3360, ab0abb1)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.25 — May 22, 2026

@kubb/parser-md

Features

  • Add @kubb/parser-md for emitting .md and .markdown files. The parser exposes parserMd.print for serialising frontmatter objects to YAML envelopes and reads file.meta.frontmatter to prepend frontmatter automatically.

    Add markdown components to @kubb/renderer-jsxFrontmatter, Heading, Paragraph, CodeBlock, List, Callout — for authoring .md files declaratively in JSX. Callout emits GitHub-style alert syntax (> [!TIP]) portable across GitHub, GitLab, VitePress, Obsidian, and MDX. (#3358, 8154649)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.24 — May 21, 2026

@kubb/core

Features

  • Expose print on parserTs and parserTsx, slim @kubb/parser-ts public API to just those two parsers.

    Parser (from @kubb/core) now requires a print(...nodes): string method that renders compiler AST nodes for the parser's language. The TypeScript and TSX parsers implement it via parserTs.print(...) / parserTsx.print(...).

    @kubb/parser-ts no longer re-exports the standalone helpers print, safePrint, createImport, createExport, or validateNodes. Plugins that depended on print / safePrint should call parserTs.print(...) instead. Custom parsers built with defineParser need to add a print implementation matching their AST node shape. (#3356, 69e8c5a)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.23 — May 21, 2026

@kubb/agent

Features

  • Forward additional Kubb lifecycle events to Studio for full event parity with @kubb/core.

    The agent now relays kubb:lifecycle:start, kubb:lifecycle:end, kubb:build:start, kubb:build:end, kubb:format:start, kubb:format:end, kubb:lint:start, kubb:lint:end, and kubb:generation:summary over the Studio WebSocket. Studio can now render a complete build timeline (per-config build span, format/lint phases) and final generation summary (duration, file count, failed plugins). (#3344, 4476049)

@kubb/cli

Bug Fixes

  • Pass the full CLI options to user-defined config functions.

    defineConfig(({ watch, logLevel, config }) => ...) now actually receives watch, logLevel, and config at runtime. Previously the CLI runner cast { input } to CLIOptions, so the other fields were silently undefined even though the type promised otherwise.

    CLIOptions.input is now a documented field (so the cast disappears) and CLIOptions.logLevel adds the missing 'verbose' value to match the CLI's --logLevel flag.

    ts
    // Now works as expected
    export default defineConfig(({ watch }) => ({
      input: { path: './petStore.yaml' },
      output: { path: './src/gen', clean: !watch },
    }))
    ``` ([#3346](https://github.com/kubb-labs/kubb/pull/3346), [`aa8aad3`](https://github.com/kubb-labs/kubb/commit/aa8aad31bf902dc83acf2f2e316d1a4e0b3c8d8c))

kubb

Bug Fixes

  • Correct the JSDoc on defineConfig: output.format and output.lint default to false, not 'auto'. The code already applies false when the user does not set either option; only the comment was wrong. (#3346, aa8aad3)
  • defineConfig now defaults root to process.cwd() when omitted. This fixes The "paths[0]" argument must be of type string. Received undefined thrown after successful generation when kubb.config.ts did not define root (the CLI then called path.resolve(config.root, …) on the un-normalized config). @kubb/core's internal resolveConfig already defaulted root for the driver, so generation itself succeeded — the error fired in the CLI's post-generation outputPath resolution. (#3352, 49a60c8)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.22 — May 20, 2026

@kubb/core

Bug Fixes

  • Make sure we can exclude/include operations (fa572bb)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.21 — May 20, 2026

@kubb/ast

Features

  • Standardize null vs undefined across the codebase: Kubb-controlled "absent" or "skip" states now use null explicitly; undefined is reserved for optional TypeScript properties and external/user-supplied values.

    Breaking changes

    @kubb/ast

    narrowSchema now returns T | null instead of T | undefined when the node type does not match.

    ts
    // Before
    const objectNode = narrowSchema(node, 'object') // ObjectSchemaNode | undefined
    
    // After
    const objectNode = narrowSchema(node, 'object') // ObjectSchemaNode | null

    collectImports resolve callback must return TImport | null (instead of TImport | undefined) to skip an import.

    ts
    // Before
    collectImports({ node, nameMapping, resolve: (name) => undefined })
    
    // After
    collectImports({ node, nameMapping, resolve: (name) => null })

    CollectVisitor<T> callbacks may now return T | null | undefined; both null and undefined are treated as "skip this node".

    RefSchemaNode.schema is now SchemaNode | null | undefinednull means the ref was resolved but circular or unresolvable; undefined means resolution was not attempted.

    keysToOmit on RequestBodyContent and ResponseNode now accepts Array<string> | null.

    InputMeta.baseURL is now string | null.

    @kubb/core

    FileManager.setOnUpsert now accepts null to detach the callback (previously undefined).

    @kubb/adapter-oas

    resolveBaseUrl now returns string | null (previously string | undefined) when serverIndex is omitted or out of range. (#3334, 2164a73)

@kubb/core

Features

  • Performance improvements and event API cleanup in KubbDriver and FileManager.

    Breaking changes

    kubb:file:processing:update (singular, fired once per file) is replaced by kubb:files:processing:update (plural, fired once per flush chunk with a files array). Update any listener from:

    ts
    hooks.on('kubb:file:processing:update', ({ file, source, processed, total, percentage, config }) => {
      // handle one file
    })

    to:

    ts
    hooks.on('kubb:files:processing:update', ({ files }) => {
      for (const { file, source, processed, total, percentage, config } of files) {
        // handle each file
      }
    })

    KubbFileProcessingUpdateContext is renamed to KubbFileProcessingUpdate (the per-item type). A new KubbFilesProcessingUpdateContext wraps files: Array<KubbFileProcessingUpdate>.

    Performance improvements

    • FileManager sorts lazily: the sorted view is rebuilt from #cache only when files is read, not on every add/upsert. Upserts are now O(1) with a single null assignment to mark the view stale.
    • FileManager.#store fast-paths single-file calls (the common case) — skips the intermediate deduplication Map.
    • mergeFile avoids unnecessary array allocations when one side's sources/imports/exports is empty — returns the non-empty reference directly.
    • createFile (SHA-256 + import/export combining) is skipped for new files that don't require merging with an existing cache entry.
    • kubb:generate:schema and kubb:generate:operation are gated on listenerCount — for builds with no listeners on these channels the per-node emit overhead is eliminated entirely.
    • FileProcessor is a long-lived class field on KubbDriver rather than a per-run() scoped resource.
    • dispose() methods added to FileProcessor, Kubb, and Renderer implementations, with [Symbol.dispose]() delegating to them consistently across the codebase. (#3334, 2164a73)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.20 — May 20, 2026

@kubb/adapter-oas

Features

  • All OpenAPI specs now go through the streaming path, removing the size-based threshold that previously switched between eager and lazy parsing.

    The adapter's internal streaming logic is extracted into a dedicated stream.ts module (preScan, createInputStream, resolveBaseUrl) so it can be tested in isolation without going through the full adapter pipeline.

    preScan and the other internal ensure* helpers each run at most once per adapter instance. Concurrent callers (e.g. stream() and parse() called simultaneously) share the same in-flight work and cannot trigger duplicate parses or validation passes. (#3331, fd3a585)

@kubb/ast

Features

  • InputMeta gains two pre-computed fields that plugins previously had to derive themselves by iterating the full schema list.

    • circularNames — names of schemas that participate in a circular reference chain. Replaces calling ast.findCircularSchemas(inputNode.schemas) inside each plugin.
    • enumNames — names of every enum schema in the document. Replaces filtering the schema stream by type.

    Both fields are plain readonly string[] arrays, keeping InputMeta fully JSON-serializable.

    GeneratorContext now exposes meta: InputMeta instead of inputNode: InputNode. Plugins that previously destructured inputNode to access circular or enum information should switch to ctx.meta.circularNames and ctx.meta.enumNames. (#3331, fd3a585)

@kubb/core

Features

  • KubbDriver and createKubb are cleaned up around the always-stream architecture.

    • STREAM_SCHEMA_THRESHOLD constant is removed. All builds now go through the streaming code path regardless of spec size.
    • Studio-related state (source, isOpen, inputNode) is consolidated into a single #studio object on KubbDriver instead of three separate private fields.
    • runAstPlugin is removed from createKubb. runPlugins is the only plugin runner now.
    • Plugin lifecycle events (kubb:plugin:start, kubb:plugin:end) fire for every plugin, including those without an adapter configured.
    • middlewareListeners, #eventGeneratorPlugins, and hasEventGenerators replace the previous public middlewareListeners, #pluginsWithEventGenerators, and hasRegisteredGenerators for naming consistency.
    • forBatches no longer accepts a flushInterval option. The flush callback now runs after every batch; callers that need coalescing should do so inside their own flush implementation. (#3331, fd3a585)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.19 — May 19, 2026

@kubb/core

Bug Fixes

  • Significantly reduce per-file overhead in the code-generation pipeline.

    • @kubb/parser-ts parse is now synchronous — returns string directly instead of Promise<string> | string. FileProcessor.stream is a plain Generator instead of AsyncGenerator, removing a microtask per file. The emitImport / emitExport string-emit helpers have been removed; import and export statements are generated through the TypeScript compiler API as before.
    • @kubb/core Renderer.stream now returns Iterable<FileNode> only — AsyncIterable support has been dropped. Parser.parse is typed as string (synchronous). Adapter initialisation consolidates the streaming / non-streaming branches, removing a duplicate debug-log path. flushPendingFiles removes a dead snapshot parameter.
    • @kubb/adapter-oas caches the underlying BaseOas instance and the schema parser at adapter scope so the schemas and operations iterables share one instance instead of rebuilding indexes per pass.
    • @kubb/renderer-jsx jsxRendererSync returns a synchronous Generator from stream, letting consumers skip the per-file microtask. (#3327, 014004f)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.18 — May 18, 2026

@kubb/adapter-oas

Bug Fixes

@kubb/core

Bug Fixes

  • Add Symbol.dispose support: FileManager and PluginDriver implement [Symbol.dispose](). safeBuild() uses using instead of try/finally. Fix resource leaks: chokidar watcher closes on SIGINT/SIGTERM; Studio WebSocket message listener removed in cleanup(); MCP HTTP server closes gracefully on signal. (#3321, 03ad8ce)

@kubb/renderer-jsx

Bug Fixes

  • Add jsxRendererSync — a React-free recursive renderer 2–4× faster than jsxRenderer. Add stream() for incremental file processing. Node attributes use plain objects instead of Map. jsxRenderer is unchanged; all new APIs are additive. (#3319, 6ab3a5e)

Contributors

Thanks to everyone who contributed to this release:

@Ericlm, @stijnvanhulle

v5.0.0-beta.17 — May 18, 2026

kubb

Features

  • Add @kubb/mcp as a direct dependency so kubb mcp works out of the box without a separate install step. (#3317, 4066e7a)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.16 — May 18, 2026

@kubb/core

Features

  • Add FileProcessor.stream() — an async generator that yields one ParsedFile at a time. run() now delegates to stream() internally, removing the mode: 'sequential' | 'parallel' option and the p-limit dependency. safeBuild() now flushes files after each plugin rather than all at once. (#3310, 7dffff1)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.15 — May 17, 2026

@kubb/ast

Features

  • Performance improvements for large OpenAPI specs: add mergeAdjacentObjectsLazy for lazy stateful merging of adjacent allOf schemas; memoize collectReferencedSchemaNames with a WeakMap. (#3305, 62f72dd)

@kubb/adapter-oas

Bug Fixes

  • Replace flatMap content-type loop with for/push (7× faster for typical 2–4 content types). (#3305, 62f72dd)

@kubb/core

Features

  • Parallelize per-node generator dispatch with Promise.all. Convert fsStorage directory walk to an async generator for streaming traversal. (#3305, 62f72dd)

@kubb/cli

Bug Fixes

  • Show live progress for formatter, linter, and custom hooks in the CLI. The clack logger now renders a live taskLog per hook that streams subprocess output while it runs. (#3306, dfa488a)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.14 — May 16, 2026

@kubb/ast

Features

  • Export collectLazy() — a generator version of collect() that yields results one at a time without materializing an intermediate array. getChildren() and collectRefs() are now generators internally. containsCircularRef() exits at the first match. (#3301, 647207f)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.13 — May 16, 2026

@kubb/cli

Bug Fixes

  • Fix multiple configs in defineConfig array stopping after the first failure. Each config is now processed independently; the process exits with code 1 after all configs complete if any failed. Middleware listeners are tracked and removed via SetupResult.dispose() between runs to prevent duplicate output. (#3297, d66969f)

@kubb/middleware-barrel

Features

  • getBarrelFiles now returns a Generator<FileNode> instead of Array<FileNode>. Iterate with for...of or spread with [...getBarrelFiles({ ... })]. (#3294, 164881b)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.12 — May 15, 2026

@kubb/adapter-oas

Bug Fixes

  • Memoize $ref resolution within parse() so each $ref is resolved at most once. Stripe (~1 400 schemas) went from OOM at 8 GB to ~840 ms / ~15 MB. (#3293, 3f5504b)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.11 — May 14, 2026

@kubb/ast

Features

  • Reduce peak memory by leaning on the existing Storage abstraction. BuildOutput.sources is replaced by BuildOutput.storage — a read-through Storage view backed by config.storage. FileProcessor now exposes a typed events property with start, update, and end events; the previous onStart, onUpdate, and onEnd callback options are removed. Kubb.driver and Kubb.config now throw if accessed before setup() instead of returning undefined. (#3285, ec10ea8)

@kubb/core

Bug Fixes

  • Further reduce peak memory: files are written after each plugin completes and already-written files are skipped via a writtenPaths set. PluginDriver.dispose() clears #resolvers and #defaultResolvers. createSourcesView.getKeys iterates the Set directly instead of materialising the full key array. (#3285, 0752d86)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.10 — May 12, 2026

@kubb/ast

Bug Fixes

  • Fix ThisType augmentation in AST resolver type. (7a6ba31)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.9 — May 12, 2026

@kubb/core

Bug Fixes

  • Add ThisType to core resolver type. (54e54b4)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.8 — May 12, 2026

@kubb/parser-ts

Bug Fixes

  • Extract utility functions from parserTs.ts into a dedicated utils.ts module for improved testability. No public API changes. (0558297)

@kubb/renderer-jsx

Breaking Changes

  • Remove createRenderer export. Use jsxRenderer() directly to obtain a renderer instance. jsxRenderer is now a plain factory function with no dependency on @kubb/core, resolving the circular package dependency. (0558297)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.7 — May 12, 2026

@kubb/cli

Bug Fixes

  • Refactor CLI runners into per-command folders (runners/generate/, runners/validate/, etc.), each with a dedicated run.ts and utils.ts. Fixes import.meta.resolve build warning and a faulty path-traversal guard in hasPackageJson. (#3268, 5030b03)

@kubb/middleware-barrel

Bug Fixes

  • Align unplugin generation defaults with the main Kubb config flow and declare the middleware barrel AST runtime dependency. (2bf409c)

unplugin-kubb

Bug Fixes

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.6 — May 9, 2026

@kubb/adapter-oas

Breaking Changes

  • Remove parseDocument, parseFromConfig, and validateDocument from the public API. Use adapter.validate(input, options?) instead. (#3249, 8a666d7)

@kubb/agent

Bug Fixes

  • Fix agent Docker build: copy full jiti package so dist/babel.cjs is available at runtime. (62fb218)

@kubb/cli

Bug Fixes

  • Make @kubb/adapter-oas an optional peer dependency for the kubb validate command — lazy-loaded only when validation runs. (#3247, 38f92e9)
  • Add --port (-p) and --host options to the mcp command for HTTP MCP server mode. (#3254, 5fa651a)

@kubb/core

Features

  • Add required validate method to the Adapter<T> type so all adapters must implement validation support. (#3249, 8a666d7)

@kubb/mcp

Features

  • Replace @modelcontextprotocol/sdk with tmcp for full TypeScript inference from Zod schemas. Add validate and init MCP tools. Export createMcpServer. Add HTTP transport support via --port flag. (#3254, 5fa651a)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.5 — May 6, 2026

@kubb/agent

Bug Fixes

  • Add @kubb/parser-ts to the default KUBB_PACKAGES build ARG in the agent Dockerfile. (#3233, 23d60be)
  • Fix Docker build failure on distroless image by replacing RUN chown with --chown flags on COPY instructions. (#3231, 2fe62b5)
  • Replace unrun with jiti for loading TypeScript config files at runtime — pure JavaScript, no native binaries. (ea3233b)

@kubb/cli

Bug Fixes

  • Replace unrun with jiti for loading TypeScript config files at runtime. (ea3233b)

@kubb/mcp

Bug Fixes

  • Replace unrun with jiti for loading TypeScript config files at runtime. (ea3233b)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.4 — May 3, 2026

@kubb/adapter-oas

Features

  • Ship an extension.yaml manifest (kind: adapter) describing the package's options, examples, and resources. References the shared extension.json schema for IDE validation. (#3224, 0542031)

@kubb/core

Features

  • Make adapter and input optional in Config to support plugin-only mode. When adapter is omitted, Kubb skips the spec parse phase and runs using only its file-management layer. (#3226, 81fbfae)

@kubb/middleware-barrel

Features

  • Ship an extension.yaml manifest (kind: middleware). (#3224, 0542031)

@kubb/parser-ts

Features

  • Ship an extension.yaml manifest (kind: parser). (#3224, 0542031)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.3 — Apr 30, 2026

@kubb/ast

Bug Fixes

  • Fix combineImports producing duplicate object-named import specifiers. Set-based deduplication failed for object import names because objects are compared by reference; the fix memoizes (propertyName, name) pairs so identical specifiers reuse the same object reference. (#3217, 4759c9c)

@kubb/cli

Bug Fixes

  • Move @kubb/agent and @kubb/mcp to optional peerDependencies to reduce default install size. (#3215, 9ecce54)

kubb

Bug Fixes

  • Move @kubb/agent and @kubb/mcp to optional peerDependencies to reduce default install size. (#3215, 9ecce54)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.2 — Apr 30, 2026

@kubb/adapter-oas

Features

  • Change the default value of integerType from 'number' to 'bigint'. int64 fields are now mapped to bigint by default; set integerType: 'number' to preserve the previous behaviour. (#3209, 9e90cbb)

@kubb/ast

Features

  • Fix include filter not preventing generation of component schemas from excluded operations. Only schemas transitively referenced by included operations are now generated. New export: collectUsedSchemaNames(operations, schemas). (#3208, 3cd3a09)

Bug Fixes

  • Fix combineImports incorrectly tree-shaking aliased named imports — the used-check now tests the alias rather than the original export name. (#3212, 0e5bfaa)

@kubb/core

Bug Fixes

  • Fix include filter scoping: only schemas reachable from included operations are generated. (#3208, 3cd3a09)

@kubb/middleware-barrel

Breaking Changes

  • Replace string-based barrelType with an object-based barrel configuration. Root config: barrel?: { type: 'all' | 'named' } | false. Plugin level: barrel?: { type: 'all' | 'named', nested?: boolean } | false. barrelType: 'propagate' becomes barrel: { type: 'all' | 'named', nested: true }. (#3200, 3519370)

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle

v5.0.0-beta.1 — Apr 29, 2026

kubb

Bug Fixes

Contributors

Thanks to everyone who contributed to this release:

@stijnvanhulle