new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Zod · all subjects

json schema output

28 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Built-in JSON Schema conversion

Zod has built-in JSON Schema conversion functionality.

JSON Schema conversion introduced in Zod 4

Zod has supported native JSON Schema conversion since version 4.0. JSON Schema is a standard for describing the structure of JSON using JSON itself, and is widely used in OpenAPI definitions and for defining structured outputs for AI systems.

z.toJSONSchema() converts Zod schemas to JSON Schema

The z.toJSONSchema() function converts a Zod schema to JSON Schema format. It takes a schema as the first argument and an optional configuration object as the second argument. By default, z.object() schemas are converted with additionalProperties: false.

Types that cannot be represented in JSON Schema

The following Zod types cannot be represented in JSON Schema and will cause an error by default: z.bigint(), z.int64(), z.symbol(), z.undefined(), z.void(), z.date(), z.map(), z.set(), z.transform(), z.nan(), and z.custom().

ToJSONSchemaParams interface and options

z.toJSONSchema() accepts a ToJSONSchemaParams object with the following fields: target (JSON Schema version: 'draft-04', 'draft-07', 'draft-2020-12', or 'openapi-3.0'; default 'draft-2020-12'), metadata (registry for looking up schema metadata), unrepresentable (how to handle unrepresentable types: 'throw' or 'any'; default 'throw'), cycles (how to handle cycles: 'ref' or 'throw'; default 'ref'), reused (how to handle reused schemas: 'ref' or 'inline'; default 'inline'), uri (function to convert id values to URIs for external $refs; default identity function), io (whether to use 'input' or 'output' type for schemas with different input/output types; default is output).

io option for input vs output types in JSON Schema conversion

Some schema types have different input and output types, such as ZodPipe, ZodDefault, and coerced primitives. By default, z.toJSONSchema() represents the output type. Use { io: 'input' } to extract the input type instead. For example, z.string().transform(val => val.length).pipe(z.number()) produces { type: 'number' } by default, but { type: 'string' } with { io: 'input' }.

target parameter for JSON Schema version selection

The target parameter in z.toJSONSchema() options specifies the JSON Schema version to target. Supported values are 'draft-04', 'draft-07', 'draft-2020-12' (default), and 'openapi-3.0'.

metadata and .meta() for adding JSON Schema metadata

Metadata can be stored using the .meta() convenience method (in Zod full) or .register(z.globalRegistry, {...}) method (in Zod Mini) to register a schema in z.globalRegistry. All metadata fields get copied into the resulting JSON Schema. For example: z.string().meta({ title: 'Email address', description: 'Your email address' }).

unrepresentable option handling in JSON Schema conversion

By default, z.toJSONSchema() throws an error when encountering unrepresentable types. Setting { unrepresentable: 'any' } converts unrepresentable types to {} (equivalent to unknown in JSON Schema). Use the override option to handle some unrepresentable types while keeping errors for others.

cycles option for handling recursive schemas in JSON Schema

By default, z.toJSONSchema() handles cycles by breaking them using $ref (cycles: 'ref'). Setting { cycles: 'throw' } will throw an error instead when a cycle is encountered.

reused option for handling repeated schemas in JSON Schema

By default, z.toJSONSchema() inlines schemas that occur multiple times (reused: 'inline'). Setting { reused: 'ref' } extracts these schemas into $defs. For example, if the same schema is used for firstName and lastName fields, the inline mode repeats the definition, while ref mode creates a shared definition in $defs.

override option for custom JSON Schema conversion logic

The override option accepts a callback function that receives a context object with zodSchema (the original Zod schema) and jsonSchema (the default JSON Schema). The function should directly modify ctx.jsonSchema. The override runs before the unrepresentable error is thrown, allowing custom handling of unrepresentable types without disabling the error for others.

String format conversions to JSON Schema

Zod converts the following string validation methods to JSON Schema format attribute: z.email() => { type: 'string', format: 'email' }, z.iso.datetime() => { type: 'string', format: 'date-time' }, z.iso.date() => { type: 'string', format: 'date' }, z.iso.duration() => { type: 'string', format: 'duration' }, z.ipv4() => { type: 'string', format: 'ipv4' }, z.ipv6() => { type: 'string', format: 'ipv6' }, z.uuid() => { type: 'string', format: 'uuid' }, z.guid() => { type: 'string', format: 'uuid' }, z.url() => { type: 'string', format: 'uri' }.

String encoding conversions to JSON Schema

z.base64() is converted to { type: 'string', contentEncoding: 'base64' }. String formats without direct JSON Schema equivalents (iso.time, base64url, cuid, emoji, nanoid, cuid2, ulid, cidrv4, cidrv6, mac) are supported via pattern attribute.

Numeric type conversions to JSON Schema

Zod converts numeric types as follows: z.number() => { type: 'number' }, z.float32() => { type: 'number', exclusiveMinimum: ..., exclusiveMaximum: ... }, z.float64() => { type: 'number', exclusiveMinimum: ..., exclusiveMaximum: ... }, z.int() => { type: 'integer' }, z.int32() => { type: 'integer', exclusiveMinimum: ..., exclusiveMaximum: ... }.

Object schema additionalProperties in JSON Schema conversion

By default, z.object() schemas are converted with additionalProperties: false, which accurately reflects Zod's default behavior of stripping additional properties. When converting in 'input' mode, additionalProperties is not set. z.looseObject() never sets additionalProperties: false, while z.strictObject() always sets additionalProperties: false.

File schema conversion to JSON Schema

z.file() is converted to { type: 'string', format: 'binary', contentEncoding: 'binary' }. Size and MIME checks are also represented: z.file().min(1).max(1024 * 1024).mime('image/png') becomes { type: 'string', format: 'binary', contentEncoding: 'binary', contentMediaType: 'image/png', minLength: 1, maxLength: 1048576 }.

Nullability conversion to JSON Schema

z.null() is converted to { type: 'null' } in JSON Schema. z.undefined() is unrepresentable in JSON Schema. z.nullable(z.string()) is converted to { oneOf: [{ type: 'string' }, { type: 'null' }] }. Optional schemas are represented as-is with an optional annotation, for example z.optional(z.string()) => { type: 'string' }.

z.fromJSONSchema() converts JSON Schema to Zod schemas

The z.fromJSONSchema() function converts a JSON Schema into a Zod schema. This functionality is experimental and not considered part of Zod's stable API; it is likely to undergo implementation changes in future releases.

Registries for generating multiple linked JSON Schemas

When you have multiple interdependent Zod schemas, you can register them with z.globalRegistry using z.globalRegistry.add(Schema, {id: 'SchemaName'}) and then pass the registry to z.toJSONSchema(z.globalRegistry). All schemas in the registry must have a registered id property; schemas without an id are ignored. The result is an object with a schemas property containing all registered schemas with $ref links between them.

uri option for absolute URIs in JSON Schema $refs

By default, z.toJSONSchema() generates simple relative path $refs like 'User'. The uri option accepts a function that converts an id to a fully-qualified URI, allowing refs like 'https://example.com/User.json'. Example: z.toJSONSchema(z.globalRegistry, { uri: (id) => `https://example.com/${id}.json` }).

z.toJSONSchema() example with basic schema

Example code: const schema = z.object({ name: z.string(), age: z.number(), }); z.toJSONSchema(schema) // => { // type: 'object', // properties: { name: { type: 'string' }, age: { type: 'number' } }, // required: [ 'name', 'age' ], // additionalProperties: false, // }

z.toJSONSchema() with override for z.date()

Example code: const result = z.toJSONSchema(z.date(), { override: (ctx) => { const def = ctx.zodSchema._zod.def; if(def.type === 'date'){ ctx.jsonSchema.type = 'string'; ctx.jsonSchema.format = 'date-time'; } }, }); This example shows how to use the override option to represent z.date() as an ISO datetime string in JSON Schema.

z.toJSONSchema() with io option for input type

Example code: const mySchema = z.string().transform(val => val.length).pipe(z.number()); const jsonSchema = z.toJSONSchema(mySchema); // => { type: 'number' } const jsonSchema = z.toJSONSchema(mySchema, { io: 'input' }); // => { type: 'string' }

z.fromJSONSchema() example

Example code: const jsonSchema = { type: 'object', properties: { name: { type: 'string' }, age: { type: 'number' }, }, required: ['name', 'age'], }; const zodSchema = z.fromJSONSchema(jsonSchema);

Registries example with User and Post schemas

Example code: const User = z.object({ name: z.string(), get posts(){ return z.array(Post); } }); const Post = z.object({ title: z.string(), content: z.string(), get author(){ return User; } }); z.globalRegistry.add(User, {id: 'User'}); z.globalRegistry.add(Post, {id: 'Post'}); z.toJSONSchema(z.globalRegistry);

z.toJSONSchema() converts schemas to JSON Schema

Call z.toJSONSchema(schema) to convert a Zod schema to JSON Schema format. Any metadata in z.globalRegistry is automatically included in the output.

z.toJSONSchema() example output

z.toJSONSchema(z.object({name: z.string(), points: z.number()})) produces: { type: 'object', properties: { name: {type: 'string'}, points: {type: 'number'} }, required: ['name', 'points'] }

Give your agent this brain