JSON to Zod Schema Generator
Turn a JSON sample into a ready-to-use Zod schema. Infers primitives, arrays, unions, and nested objects, detects string formats (email, URL, UUID, date-time), marks missing keys optional and mixed-null keys nullable, and names the root schema.
Input
Variable name for the root schema (its z.infer type is PascalCased).
z.object() strips unknown keys; .passthrough() keeps them.
CommonJS emits const { z } = require('zod') and omits the TypeScript type alias.
Output
Guides
Paste a JSON sample and get a matching Zod schema in TypeScript, ready to copy into your project. Instead of hand-writing z.object({ ... }) by staring at an API response, you drop the response in and the generator infers the shape for you — primitives, arrays, unions, and deeply nested objects included.
What it does
The tool walks your JSON and emits Zod code as plain text (it never runs Zod itself). Each value maps to the closest Zod type:
- Strings become
z.string()— and it recognizes common formats, upgrading toz.string().email(),z.string().url(),z.string().uuid(), orz.string().datetime()when a value looks like one. - Whole numbers become
z.number().int(); numbers with a decimal becomez.number(). - Booleans become
z.boolean(), andnullbecomesz.null(). - Objects become nested
z.object({ ... })blocks, indented for readability. - Arrays become
z.array(...). If the items are all the same type you get a clean inner type; if they differ you getz.array(z.union([...])).
How to use it
- Paste or type your JSON into the input box.
- Set a Schema name — this is the exported variable, and its
z.infertype is the PascalCased version (e.g.user→User). - Choose how to handle unknown keys: strip them with a plain
z.object(), or keep them with.passthrough(). - Toggle the
import { z } from "zod"line and thez.infertype alias on or off. - Copy or download the generated
.tsfile.
The output updates automatically as you type, so you can tweak the JSON and watch the schema change.
How are arrays of objects handled?
When the top level (or any array) contains only objects, their shapes are merged into one element schema. A key that is present in every object stays required; a key missing from some objects is marked .optional(). This mirrors how real API collections drift over time.
What about null values?
If a key is sometimes null and sometimes has a real value, the real type is wrapped in .nullable() (e.g. z.number().nullable()). If a key is only ever null in your sample, it becomes z.null() — swap that for a concrete .nullable() type once you know the real shape.
Does it detect string formats correctly?
It uses pattern matching, so "2024-01-15T10:30:00Z" becomes z.string().datetime() and "ada@example.com" becomes z.string().email(). These are best-effort guesses from a single sample — review them and relax any that are too strict for your data.
Is my data uploaded anywhere?
No. Everything runs entirely in your browser. Your JSON is parsed and converted locally, nothing is sent to a server, and nothing is stored. You can paste sensitive payloads with confidence, and the tool keeps working offline once the page has loaded.