Skip to content

JSON to Zod Schema Converter

Paste JSON, get a ready-to-use Zod schema instantly, 100% in your browser. Correct z.number().int(), .optional() and .nullable(), plus a z.infer type. Free.

No Tracking Runs in Browser Free
Options
0 chars
Zod Output
0 lines
Output verified against Zod v3 and v4 parsing semantics for real-world API payloads. — Go Tools Team · Jul 2, 2026

What is a Zod schema?

A Zod schema is a TypeScript-first description of a value's shape that validates data at runtime and infers a static type at compile time. Generating one from a JSON sample means you never hand-write validation boilerplate for API responses, forms, or config files. This Zod schema generator infers correct types, marks absent keys as .optional(), null values as .nullable(), and hands you a z.infer type — all 100% in your browser.

Examples

API response

{"id":101,"name":"Ada Lovelace","email":"ada@example.com","active":true,"roles":["admin","user"]}
import { z } from "zod";

export const RootSchema = z.object({
  id: z.number().int(),
  name: z.string(),
  email: z.string(),
  active: z.boolean(),
  roles: z.array(z.string()),
});

export type Root = z.infer<typeof RootSchema>;

A typical REST payload becomes a ready-to-use Zod schema. Whole numbers infer z.number().int(), and the roles array becomes z.array(z.string()). A z.infer type comes free.

Nested object

{"repo":"zod","owner":{"login":"colinhacks","id":100}}
import { z } from "zod";

export const OwnerSchema = z.object({
  login: z.string(),
  id: z.number().int(),
});

export const RootSchema = z.object({
  repo: z.string(),
  owner: OwnerSchema,
});

export type Root = z.infer<typeof RootSchema>;

Nested objects become their own named schema (OwnerSchema) and are referenced by field. Child schemas are declared before the parent that uses them, and identical shapes are declared once and reused.

Array of objects (optional field)

{"users":[{"id":1,"nick":"x"},{"id":2}]}
import { z } from "zod";

export const UserSchema = z.object({
  id: z.number().int(),
  nick: z.string().optional(),
});

export const RootSchema = z.object({
  users: z.array(UserSchema),
});

export type Root = z.infer<typeof RootSchema>;

Arrays of objects merge into one element schema. A key missing from some items becomes .optional(), so parsing still succeeds when it is absent.

Nullable field & number unification

{"items":[{"sku":"A1","discount":0.1},{"sku":"A2","discount":null}]}
import { z } from "zod";

export const ItemSchema = z.object({
  sku: z.string(),
  discount: z.number().nullable(),
});

export const RootSchema = z.object({
  items: z.array(ItemSchema),
});

export type Root = z.infer<typeof RootSchema>;

A field that is null in some samples but typed in others becomes .nullable(). Because 0.1 has a decimal point, the number unifies to z.number() rather than z.number().int().

How to convert JSON to Zod

  1. 1

    Paste your JSON

    Drop a JSON object, array, or API response into the input box. Conversion starts instantly.

  2. 2

    Tune the output

    Rename the root schema and toggle the import line, z.infer type, or export keyword to match your project's style.

  3. 3

    Copy or download

    Grab the generated Zod schema with one click and paste it straight into your validation layer.

Common Use Cases

Validate API responses
Turn a sample REST or GraphQL response into a Zod schema and parse it at the fetch boundary, so malformed data fails fast with a clear error instead of leaking through your app.
Type-safe forms and inputs
Generate a schema for form or query input and reuse the z.infer type across your UI and handlers for end-to-end type safety.
tRPC and AI tool schemas
Bootstrap input and output schemas for tRPC procedures or AI structured-output tools from an example payload instead of writing them by hand.

How the conversion works

Structural inference
Each object becomes a named schema; identical shapes are declared once and reused. Arrays of objects merge key by key, and keys absent from some items become .optional().
Correct type mapping
Integers map to z.number().int() and decimals to z.number(). Strings, booleans, and nulls map to z.string(), z.boolean(), and z.null(); an array of mixed primitives becomes a z.union().
TypeScript types included
A z.infer type alias is emitted for the root schema, so the schema stays the single source of truth and your types never drift from your validation.
100% client-side
Parsing and generation run in your browser with no network calls, so your data stays private.

Tips for clean Zod schemas

Name your root schema
Set a meaningful root name such as User or ApiResponse instead of the default Root for readable, self-documenting code.
Refine z.unknown() and unions
Empty or mixed arrays produce z.unknown() or a broad z.union(). Paste a richer, representative sample so the tool infers precise types, then tighten anything that stays ambiguous.
Validate at the boundary
Call safeParse() where untrusted data enters — API responses, form input, webhooks — so bad data is caught before it reaches your application logic.

Frequently asked questions

How do I convert JSON to a Zod schema?
Paste your JSON into the box on the left. The converter parses it instantly in your browser and generates a Zod schema on the right, together with a z.infer type alias. Click Copy to grab it — no upload, no account, no waiting.
What is the difference between JSON to Zod and JSON Schema to Zod?
This tool takes a sample JSON value — an API response or object — and infers a Zod schema from its shape. JSON Schema to Zod is a different task: it converts an existing JSON Schema document into Zod. If you have raw data, use this tool. If you already have a JSON Schema file, convert that instead.
How do I get a TypeScript type from the schema?
Every result includes a z.infer type alias, so you get a fully typed Root without writing it by hand. Keep the schema as the single source of truth and let TypeScript derive the type, so the two never drift apart. You can toggle the z.infer line off in Options if you only want the schema.
How are optional and null fields handled?
When a key appears in some array items but not others, its field is marked .optional(). A field that is null in some samples and typed in others becomes .nullable(). A field that is only ever null becomes z.null(). Zod treats optional and nullable independently, so the schema matches how your data actually varies.
What number type does it generate?
Whole numbers map to z.number().int(); any value written with a decimal point or exponent maps to z.number(). If a field mixes integers and decimals across samples, it unifies to z.number() so validation never rejects a legitimate value.
Does the output work with Zod 3 and Zod 4?
Yes. The generated code uses the common, stable subset — z.object, z.string, z.number, z.array, z.union, .int, .optional, .nullable and z.infer — that behaves the same in Zod 3 and Zod 4. Just make sure the zod package is installed in your project.
How do I validate data with the generated schema?
Import the schema and call RootSchema.parse(data) to throw on invalid input, or RootSchema.safeParse(data) to get a typed success or error result without throwing. This is ideal at trust boundaries such as API responses, form input, and environment config.
How are arrays and mixed types handled?
An array of one type becomes z.array of that type. An array of objects merges key by key into a single element schema. An array that mixes primitive types becomes a z.union, and anything more ambiguous falls back to z.unknown so you can refine it from a richer sample.
Is my JSON data private and safe?
Yes. Conversion runs 100% in your browser with JavaScript. Your JSON — including tokens, IDs, or customer data — never leaves the page and is never sent to a server.
Is the tool free? Do I need an account?
It is completely free with no sign-up, no limits, and no ads cluttering the workspace.

Related Tools

View all tools →