@orpc/zod package provides a Zod-to-JSON Schema converter for oRPC’s OpenAPI generator, plus a collection of extra Zod schemas for types that Zod doesn’t natively support (File, Blob, URL, RegExp).
Installation
Schema converters
@orpc/zod ships two converters — one for Zod v3 and one for Zod v4:
- Zod v4 (recommended)
- Zod v3
@orpc/zod/zod4 when using Zod v4 (zod package ≥4.0).Constructor options
Usage with OpenAPIGenerator
Extra schemas via oz
The oz namespace exposes extra schema constructors for types Zod doesn’t support natively:
oz.file()
Validates a File instance. In JSON Schema, it generates { type: 'string', contentMediaType: '*/*' }.
oz.blob()
Validates a Blob instance. In JSON Schema, it generates { type: 'string', contentMediaType: '*/*' }.
oz.url()
Validates a URL instance. In JSON Schema, it generates { type: 'string', format: 'uri', 'x-native-type': 'url' }.
oz.regexp()
Validates a RegExp instance. In JSON Schema, it generates { type: 'string', pattern: '^\\/(.*)\\/([a-z]*)$', 'x-native-type': 'regexp' }.
oz.openapi() — custom JSON Schema override
Attach custom JSON Schema metadata to any Zod schema:
Supported Zod types
The converter handles all standard Zod types:| Zod type | JSON Schema |
|---|---|
z.string() | { type: 'string' } + format/pattern from checks |
z.number() | { type: 'number' } or { type: 'integer' } |
z.boolean() | { type: 'boolean' } |
z.null() | { type: 'null' } |
z.bigint() | { type: 'string', pattern: '^-?[0-9]+$', 'x-native-type': 'bigint' } |
z.date() | { type: 'string', format: 'date-time', 'x-native-type': 'date' } |
z.array() | { type: 'array', items: ... } |
z.object() | { type: 'object', properties: ..., required: ... } |
z.record() | { type: 'object', additionalProperties: ... } |
z.enum() | { enum: [...] } |
z.union() | { anyOf: [...] } |
z.intersection() | { allOf: [...] } |
z.tuple() | { type: 'array', prefixItems: [...] } |
z.set() | { type: 'array', uniqueItems: true, 'x-native-type': 'set' } |
z.map() | { type: 'array', items: ..., 'x-native-type': 'map' } |
z.optional() | unwrapped inner schema, required: false |
z.nullable() | { anyOf: [inner, { type: 'null' }] } |
z.default() | inner schema + default value |
z.lazy() | resolves recursively up to maxLazyDepth |
z.any() / z.unknown() | {} (any value) |
