Zod 4 z.toJSONSchema()
Use the native Zod 4 z.toJSONSchema() function to convert Zod schemas to JSON Schema, pick a draft target, control input vs output, add metadata, and migrate off the deprecated zod-to-json-schema package.
Quick answer: how do you convert a Zod schema to JSON Schema in Zod 4?
Call `z.toJSONSchema(schema)`. Zod 4 ships JSON Schema conversion in core, so you no longer need the external `zod-to-json-schema` package, which stopped active maintenance in November 2025. By default it emits Draft 2020-12; pass a `target` for Draft-07 or OpenAPI 3.0.
Basic z.toJSONSchema() usage
Import Zod and pass any schema. The function returns a plain JSON Schema object you can serialize, store, or feed to a validator. Object properties, required fields, and primitive types map over directly.
import * as z from "zod";
const UserSchema = z.object({
id: z.string().uuid(),
email: z.string().email(),
age: z.number().int().optional(),
});
const jsonSchema = z.toJSONSchema(UserSchema);
// {
// $schema: "https://json-schema.org/draft/2020-12/schema",
// type: "object",
// properties: {
// id: { type: "string", format: "uuid" },
// email: { type: "string", format: "email" },
// age: { type: "integer" }
// },
// required: ["id", "email"],
// additionalProperties: false
// }Choose a draft target (Draft 2020-12, Draft-07, OpenAPI 3.0)
The biggest cause of validation failures after conversion is a draft mismatch. Set `target` to match the validator that consumes the schema. Draft 2020-12 is the default; choose Draft-07 for older Ajv setups and openapi-3.0 when pasting into an OpenAPI document.
// Draft-07 for a classic Ajv instance
const draft7 = z.toJSONSchema(UserSchema, { target: "draft-7" });
// OpenAPI 3.0 Schema Object
const openapi = z.toJSONSchema(UserSchema, { target: "openapi-3.0" });Input vs output with the io option
Schemas with `.default()`, `.catch()`, or transforms have a different shape before and after parsing. By default Zod converts the output type. Pass `io: "input"` to describe the data a client should send instead of what your app receives after parsing.
const FormSchema = z.object({
role: z.string().default("member"),
acceptedAt: z.iso.datetime(),
});
// Describes parsed output (role always present)
const outputSchema = z.toJSONSchema(FormSchema);
// Describes the request payload a client sends (role optional)
const inputSchema = z.toJSONSchema(FormSchema, { io: "input" });Add titles, descriptions, and examples with .meta()
Use `.meta()` to attach JSON Schema annotations. Metadata registered through `.meta()` lands in Zod's global registry and is included automatically in the converted output, which is how you produce self-documenting schemas for OpenAPI and AI structured outputs.
const Email = z
.string()
.email()
.meta({
title: "Email",
description: "Primary contact email",
examples: ["jane@acme.dev"],
});
z.toJSONSchema(Email);
// {
// type: "string",
// format: "email",
// title: "Email",
// description: "Primary contact email",
// examples: ["jane@acme.dev"]
// }Migrate from the zod-to-json-schema package
The community `zod-to-json-schema` package is no longer actively maintained because the native function covers the same workflow. The migration is mostly a one-line import change. Drop the dependency, switch to the core import, and move the schema-name argument into `$ref` handling if you relied on it.
- Remove `zod-to-json-schema` from package.json and delete its import lines.
- Replace `zodToJsonSchema(schema, name)` with `z.toJSONSchema(schema)` and set `target` if you previously passed draft options.
- If you bundled many schemas under `$defs`, convert them with a registry and the `reused: "ref"` option instead of the package name argument.
- Re-run your validator tests after switching the draft target so format keywords still compile.
// Before (deprecated package)
import { zodToJsonSchema } from "zod-to-json-schema";
const schema = zodToJsonSchema(UserSchema, "User");
// After (native Zod 4)
import * as z from "zod";
const schema = z.toJSONSchema(UserSchema);When to still use a converter tool instead
The native function is ideal inside application code. A browser converter is still useful for quick inspection, reviewing a teammate's schema, or generating JSON Schema without wiring up a Zod project, because it runs the same conversion behavior on pasted input.
Limitations to expect
JSON Schema cannot represent everything Zod can express, so conversion is lossy in predictable ways. Plan for these gaps before treating the output as a complete contract.
- Runtime-only checks such as `.refine()` and `.transform()` are not expressed in the JSON Schema output.
- Unrepresentable types (for example `z.bigint()`, `z.date()`, `z.map()`) throw unless you pass an `unrepresentable` fallback.
- z.toJSONSchema() produces a schema object only, not OpenAPI paths, operations, responses, or security schemes.
- Draft 2020-12 keywords like `prefixItems` will fail on validators that only understand Draft-07.
z.toJSONSchema() target options
| Target | What it emits | Use when |
|---|---|---|
| draft-2020-12 (default) | Modern JSON Schema using the 2020-12 dialect, including `$schema` and `prefixItems` for tuples. | You consume the schema with an up-to-date validator such as Ajv 2020 or store contracts in your own tooling. |
| draft-7 | Draft-07 output that older validators and many existing toolchains still expect. | Your downstream validator (default Ajv import, legacy services) targets Draft-07. |
| openapi-3.0 | An OpenAPI 3.0 Schema Object (nullable handled the 3.0 way, no 2020-12-only keywords). | You paste the result into an OpenAPI 3.0 components/schemas block. |
Use FrameworkKit to generate the starter code, then review the output before shipping it in production.
Zod to JSON Schema ConverterZod to JSON Schema resources
Zod to JSON Schema Converter
Use the canonical free online converter for Draft 2020-12, Draft 7, AJV, or OpenAPI-compatible output.
Zod to JSON Schema examples
Review object, enum, nullable, optional, array, and nested Zod conversion examples.
Zod to OpenAPI guide
Generate Swagger/OpenAPI docs from Zod schemas, compare package workflows, and choose OpenAPI 3.0 or 3.1.
Convert Zod to JSON Schema with AJV
Convert Zod to JSON Schema, choose an Ajv draft, compile validators, and avoid unsupported Zod features.
Fastify Zod validation
Use Zod schemas with Fastify request validation, response schemas, type providers, and OpenAPI output.
Zod to JSON Schema for OpenAPI
Publish OpenAPI-compatible schema output from TypeScript-owned Zod contracts.
Zod refine vs superRefine
Review why custom refinements cannot be represented as plain JSON Schema without a separate validation step.
Zod API schemas
Use Zod at API request and response boundaries before publishing or validating contracts.
Zod vs JSON Schema
Decide when Zod, JSON Schema, OpenAPI, and AJV should own runtime validation contracts.
FAQ
Does z.toJSONSchema replace the zod-to-json-schema package?
Yes for most use cases. Zod 4 includes native JSON Schema conversion, and the community package is no longer actively maintained. Switch the import to `z.toJSONSchema` and set a `target` if you relied on draft options.
Which draft target should I use?
Match the validator that consumes the schema. Use the default Draft 2020-12 for modern tooling, `draft-7` for older Ajv setups, and `openapi-3.0` when pasting into an OpenAPI 3.0 document.
Is z.toJSONSchema enough to generate an OpenAPI spec?
No. It converts a single schema into a JSON Schema or OpenAPI Schema Object. You still need to assemble paths, operations, request bodies, responses, and security schemes to produce a full OpenAPI document.
How do I add a description or title to the output?
Use `.meta({ title, description, examples })` on the schema. Metadata is stored in Zod's global registry and included automatically in the converted JSON Schema.
Why does conversion throw on some schemas?
Types like bigint, date, and map have no standard JSON Schema representation. Pass an `unrepresentable` fallback option or replace the field with a representable type before converting.
Related comparisons
Related tools
JSON to Zod Converter
Convert JSON to Zod schemas with strict objects, optional field inference, and inferred TypeScript types.
TypeScript to Zod Converter
Convert TypeScript interfaces and type aliases into Zod schemas with inferred types in your browser.
OpenAPI to Zod
Turn OpenAPI schemas into Zod validators and lightweight typed fetch clients.