Skip to content

Options

Options for pluginZod.

Option Type Default Description
output Output { path: 'zod', barrel: { type: 'named' } } Where the generated files are written and exported
group Group Split output into per-tag or per-path folders
importPath string mini ? 'zod/mini' : 'zod' Module the generated files import z from
inferred boolean false Emit a z.infer alias next to each schema
coercion boolean | { dates?: boolean, strings?: boolean, numbers?: boolean } false Coerce input before validation
guidType 'uuid' | 'guid' 'uuid' Validator for format: uuid properties
regexType 'literal' | 'constructor' 'literal' How an OpenAPI pattern is written
mini boolean false Generate Zod Mini schemas
include Array<Include> Keep only operations that match
exclude Array<Exclude> Skip operations that match
override Array<Override> Apply different options per pattern
resolver ResolverPatch<ResolverZod> Customize generated names and file paths
macros Array<Macro> Rewrite AST nodes before printing
printer { nodes?: PrinterZodNodes | PrinterZodMiniNodes } Replace the handler for a schema type

output

Where the generated .ts files are written and how they are exported.

output.path

Folder where the plugin writes its files, resolved against the global output.path on defineConfig. For a single file, set output.mode: 'file' and give path an extension, such as 'zod.ts'.

Type: string
Default: 'zod'

output.mode

How the plugin consolidates generated code into files.

  • 'file' (default) writes everything into a single file, so output.path must include the file extension (for example 'zod.ts').
  • 'directory' writes one file per operation or schema under output.path.
Type: 'directory' | 'file'
Default: 'file'

output.barrel

Toggle the export style and depth to see the generated barrels.

  • src/gen/
  • models/
  • Pet.ts
  • User.ts
  • clients/
  • pet/
  • getPetById.ts
  • store/
  • getInventory.ts
src/gen/index.ts

Controls how the generated index.ts (barrel) re-exports the output. Accepts { type: 'named' } or { type: 'all' }, optionally with nested: true (for example { type: 'named', nested: true }) to write an index.ts in every subdirectory, or false to skip the barrel entirely. Each generator plugin defaults output.barrel to { type: 'named' }; the root output.barrel on defineConfig defaults to false.

output.banner

Text added to the top of every generated file, such as a license header or @ts-nocheck directive. Pass a string, or a function (meta: BannerMeta) => string that receives the document info (title, description, version, baseURL) and per-file context (filePath, baseName, isBarrel, isAggregation), so a directive can skip barrel files.

Text added to the bottom of every generated file (string or (meta: BannerMeta) => string), like banner but for closing comments. Pair banner: '/* eslint-disable */' with footer: '/* eslint-enable */' to scope a lint disable to the generated file.

group

Switch the mode to see where these operations land on disk.

clients/pet/
  • getPetById
  • addPet
clients/store/
  • getInventory
clients/order/
  • placeOrder
  • getOrderById
clients/user/
  • loginUser
group: { type: "tag" } splits the output by the operation tag, so placeOrder follows its order tag.

Splits generated files into subfolders by the operation's tag or URL path, each under {output.path}/{groupName}/. Without group, every file lands directly in output.path. It applies only to output.mode: 'directory'.

IMPORTANT

Combining group with output.mode: 'file' stops the build with a KUBB_INVALID_PLUGIN_OPTIONS error.

group.type

Property used to assign each operation to a group ('tag' | 'path'), required whenever group is set. An operation with no tag goes in the default group.

  • 'tag' uses the operation's first tag.
  • 'path' uses the first URL segment, such as pet for /pet/{petId}.

group.name

Function that turns a group key (first tag or path segment) into a folder or identifier name, used as the subdirectory under output.path and a suffix for aggregate files. For type: 'path', the default keeps the URL segment as-is instead of camelCasing.

Type: (context: { group: string }) => string
Default: 'tag': ({ group }) => camelCase(group); 'path': the raw URL segment, uncased

importPath

Module specifier for the import { z } from '...' statement in every generated file, so you can re-export Zod from your own module. Defaults to 'zod', or 'zod/mini' when mini is on.

NOTE

'zod' and 'zod/mini' import the z namespace (import * as z), but a custom module imports the named z export (import { z }), so re-export z from there.

inferred

Exports a z.infer<typeof schema> type alias next to every generated schema, so the schema is the single source of truth and you do not import types from @kubb/plugin-ts. The alias is the PascalCased schema name with a SchemaType suffix, so petSchema becomes PetSchemaType.

typescript
import * as z from 'zod'

export const petSchema = z.object({
  name: z.string(),
})

export type PetSchemaType = z.infer<typeof petSchema>

coercion

Wraps schemas in z.coerce so input is coerced before validation, for form data, query params, and similar string sources.

  • true coerces strings, numbers, and dates.
  • false (default) coerces nothing and validates strictly.
  • An object picks which primitives to coerce.

See Coercion for primitives.

typescript
z.coerce.string()
z.coerce.number()
z.coerce.date()

NOTE

dates coerces only Date-typed fields (from dateType: 'date'). Fields kept as ISO strings (z.iso.date(), z.iso.datetime()) are never coerced.

guidType

Validator used for OpenAPI properties with format: uuid.

  • 'uuid' (default) generates z.uuid(), a standard RFC 4122 UUID.
  • 'guid' generates z.guid(), which is looser and accepts Microsoft-style GUIDs.

regexType

Controls how an OpenAPI pattern is written inside .regex(...).

  • 'literal' (default) emits a regex literal, such as .regex(/^[a-z]+$/).
  • 'constructor' emits the RegExp constructor, such as .regex(new RegExp('^[a-z]+$')).

Use 'constructor' when a regex literal breaks your build or you need a string pattern.

mini

Switches code generation to Zod Mini, which uses the functional API (z.optional(z.string())) instead of the chainable one (z.string().optional()) so bundlers can tree-shake unused validators. mini: true also defaults importPath to 'zod/mini'.

WARNING

Zod Mini is currently in beta. Its API may change in a future release.

typescript
import * as z from 'zod/mini'

z.optional(z.string())
z.nullable(z.number())
z.array(z.string()).check(z.minLength(1), z.maxLength(10))

include

Generates only the operations and schemas that match at least one entry, and skips the rest. Each entry filters by tag, operationId, path, method, contentType, or schemaName, with a pattern that can be a string or a RegExp, both matched as a regular expression against the value. A string pattern is compiled with new RegExp(pattern), so it is not an exact match: pattern: 'pet' also matches 'petType' or 'superpet'.

Type definition
typescript
export type Include = {
  type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType' | 'schemaName'
  pattern: string | RegExp
}

exclude

Skips any operation or schema that matches at least one entry, the opposite of include. Entries use the same type and pattern fields as include, and when both options match an item, exclude wins.

override

Applies different plugin options to operations that match a pattern. Each entry takes the same type and pattern as include, plus an options object that accepts any plugin option except override, so rules cannot nest. The first matching entry merges onto the plugin defaults, and later entries do not stack.

Type definition
typescript
export type Override = {
  type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType' | 'schemaName'
  pattern: string | RegExp
  options: Omit<Partial<Options>, 'override'>
}

For example, override: [{ type: 'tag', pattern: 'user', options: { coercion: true } }] coerces input only for the user tag.

resolver

Changes how the plugin names generated files and symbols. Pass a partial patch: override only the members you want, and anything you omit keeps resolverZod. See Override a resolver for the this context and how a patch layers over the default.

TIP

Inside a method this is the full resolver, so this.default.name(name) reuses the built-in casing.

Partial override
typescript
type ResolverZodPatch = {
  name?(name: string): string
  file?: {
    baseName?(params: { name: string; extname: string }): string
    path?(params: { baseName: string; output: Output }): string
  }
  schema?: {
    typeName?(name: string): string       // → 'PetSchemaType'
    type?(name: string): string           // → 'PetSchemaType'
    inputName?(name: string): string      // → 'orderInputSchema'
    inputTypeName?(name: string): string  // → 'OrderInputSchemaType'
  }
  param?: {
    name?(node: OperationNode, param: ParameterNode): string    // → 'deletePetPathPetIdSchema'
    path?(node: OperationNode, param: ParameterNode): string     // → 'deletePetPathSchema'
    query?(node: OperationNode, param: ParameterNode): string    // → 'findPetsByStatusQuerySchema'
    headers?(node: OperationNode, param: ParameterNode): string  // → 'deletePetHeadersSchema'
  }
  response?: {
    status?(node: OperationNode, statusCode: StatusCode): string // → 'listPetsStatus200Schema'
    body?(node: OperationNode): string                           // → 'createPetBodySchema'
    responses?(node: OperationNode): string                      // → 'listPetsResponsesSchema'
    response?(node: OperationNode): string                       // → 'listPetsResponseSchema'
    error?(node: OperationNode): string                          // → 'listPetsErrorSchema'
    options?(node: OperationNode): string                        // → 'ListPetsOptionsSchemaType'
  }
}

macros

Rewrites AST nodes before they are printed, without forking the generator. Each macro callback (such as schema or operation) receives the node and a context object, and returns a replacement or undefined to leave it as is. Omitted callbacks keep their defaults, and macros run in order, so a later one sees the output of an earlier one.

printer

Replaces the Zod handler for a schema type such as 'integer' or 'string', each returning the Zod expression as a string and targeting the Zod Mini printer when mini: true. Inside a handler, this.base(node) returns the built-in output to wrap and this.transform(node) recurses into nested nodes. See the printer guide.

typescript
import { 
pluginZod
} from '@kubb/plugin-zod'
pluginZod
({
printer
: {
nodes
: {
integer
() {
return 'z.number()' },
date
() {
return 'z.string().date()' }, }, }, })