Skip to content
Zod logo

Zod

Officialv5.9.4

@kubb/plugin-zod

kubb add plugin-zod

Zod validators for OpenAPI formats

Look up the Zod v4 call Kubb writes for each OpenAPI type and format, such as z.uuid() for format: uuid, and the keywords that add a z.refine check.

@kubb/plugin-zod reads the type and format of each schema and prints the matching Zod call. The Zod Mini column shows the output with mini: true.

Integers

OpenAPI type and formatZodZod MiniNotes
integerz.int()z.int()Coerced with coercion.numbers
integer, format: int32z.int32()z.int32()32-bit signed integer
integer, format: uint32z.uint32()z.uint32()32-bit unsigned integer
integer, format: int64z.coerce.bigint()z.coerce.bigint()Always coerced, because JSON holds a number
string, format: int32 / int64z.string().regex(/^-?\d+$/)z.string().check(z.regex(/^-?\d+$/))An integer sent as a JSON string. uint64 uses /^\d+$/. A pattern in the spec wins.

With integerType: 'number' on the adapter, format: int64 prints z.int().

Strings

OpenAPI type and formatZodZod MiniNotes
string, format: uuidz.uuid() or z.guid()z.uuid() or z.guid()Set by guidType
string, format: emailz.email()z.email()Email
string, format: uri / urlz.url()z.url()URL
string, format: hostnamez.hostname()z.hostname()Host name
string, format: ipv4 / ipv6z.ipv4() / z.ipv6()z.ipv4() / z.ipv6()IP address
string, format: base64z.base64()z.base64()Base64 string
string, format: base64urlz.base64url()z.base64url()URL-safe base64 string
string, contentEncoding: base64 / base64urlz.base64() / z.base64url()z.base64() / z.base64url()Other encodings stay z.string()
string, format: byte / binaryz.instanceof(Blob)z.instanceof(Blob)Binary payload
string, format: jwtz.jwt()z.jwt()JSON Web Token
string, format: ulidz.ulid()z.ulid()ULID
string, format: ibanz.iban()z.iban()International Bank Account Number
string, format: durationz.iso.duration()z.iso.duration()ISO 8601 duration
string, JSON contentMediaType with contentSchemaz.string().refine(...)z.string().check(z.refine(...))Must parse as JSON that passes the content schema. It stays a string.

coercion.strings replaces some of these validators with z.coerce.string().

Dates and times

OpenAPI type and formatZodZod MiniNotes
string, format: datez.iso.date()z.iso.date()ISO 8601 date
string, format: date-timez.iso.datetime()z.string()ISO 8601 date-time
string, format: timez.iso.time()z.iso.time()ISO 8601 time

These rows apply to the adapter's default dateType: 'string'.

Objects

OpenAPI type and formatZodZod MiniNotes
object, additionalProperties: <schema>z.record(z.string(), schema)z.record(z.string(), schema)Dictionary with no fixed properties
object, additionalProperties: truez.looseObject(shape)z.looseObject(shape)Allows extra keys
object, additionalProperties: falsez.strictObject(shape)z.strictObject(shape)Rejects extra keys

JSON Schema keywords

These keywords print a z.refine check in both APIs:

KeywordCheck
if/then/else, dependentRequired, dependentSchemasChecks the input before parsing, in z.pipe(z.unknown().check(...), schema).
minProperties, maxPropertiesCounts the keys of the input before parsing, in the same z.pipe(...).
propertyNames on an object that also declares propertiesChecks every key of the input. A dictionary keeps z.record(keySchema, schema).
contains with minContains and maxContainsCounts the matching items of an array.
uniqueItemsRejects an array with duplicate entries.

To change the call for one type, replace its printer handler. See Customize generated schemas.