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'writes everything into a single file, sooutput.pathmust include the file extension (for example'zod.ts').'directory'writes one file per operation or schema underoutput.path.
Leave it unset and Kubb reads output.path: a name with an extension means one file, anything else a directory.
| Type: | 'directory' | 'file' |
| Default: | follows the shape of output.path |
output.barrel#
output.banner#
output.footer#
group#
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.
import * as z from 'zod'
export const petSchema = z.object({
name: z.string(),
})
export type PetSchemaType = z.infer<typeof petSchema>
It also generates a ResponsesSchema per operation, the per-status responses record, with its inferred type. @kubb/plugin-fetch and @kubb/plugin-axios key their RequestResult on it when @kubb/plugin-ts is absent.
coercion#
Wraps schemas in z.coerce so input is coerced before validation, for form data, query params, and similar string sources.
truecoerces strings, numbers, and dates.false(default) coerces nothing and validates strictly.- An object picks which primitives to coerce.
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) generatesz.uuid(), a standard RFC 4122 UUID.'guid'generatesz.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 theRegExpconstructor, 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.
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#
exclude#
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.
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#
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.
import { pluginZod } from '@kubb/plugin-zod'
pluginZod({
printer: {
nodes: {
integer() {
return 'z.number()'
},
date() {
return 'z.string().date()'
},
},
},
})
A handler that reads this.options.direction ('decode' for responses, 'encode' for request bodies and parameters) and returns a different expression per direction registers a two-way conversion: the generator detects the difference and emits an ${name}InputSchema variant for request bodies to resolve to, including through a $ref. See Encode a custom type on requests.