JSON to Zod is a free generator that creates Zod validation schemas from example JSON, such as an API response. It detects nested objects, arrays, optional properties and nullable values, reuses schemas for repeated shapes, and exports matching TypeScript types with z.infer. It runs in your browser, so you can paste real data.
How to generate a Zod schema
- Paste a JSON example. Responses with several array items give the most accurate result.
- Name the schema and choose whether to export TypeScript types.
- Copy the code into your project, where
zodmust be installed.
Example
{ "id": 7, "owner": { "name": "Priya" }, "tasks": [{ "due": "2026-10-01" }, { "due": null }] }generates:
import { z } from 'zod';
const ownerSchema = z.object({
name: z.string(),
});
const taskSchema = z.object({
due: z.string().nullable(),
});
export const rootSchema = z.object({
id: z.number(),
owner: ownerSchema,
tasks: z.array(taskSchema),
});
export type Root = z.infer<typeof rootSchema>;Using the schema
Call rootSchema.parse(data) to validate data and throw a detailed error if it doesn’t match, orrootSchema.safeParse(data) to get a result object instead. Because the type is inferred from the schema, your types and validation can never drift apart.
Refining the output
A generated schema describes your example, not every rule your data follows. Consider tightening it:
z.string().email(),.url()or.uuid()for formatted strings, andz.string().datetime()for timestamps.z.number().int()for IDs and counts.z.enum(['draft', 'published'])for fields with a fixed set of values..optional()on fields your example happened to include but the API doesn’t always send.
Only need compile-time types? Use JSON to TypeScript, which uses the same detection.
Frequently asked questions
Why use Zod instead of TypeScript types?
TypeScript types disappear at runtime, so they cannot catch an API that returns unexpected data. A Zod schema checks the data when it arrives and gives you the TypeScript type too, via z.infer.
How are optional fields detected?
Items in arrays are compared: a property that is missing from some items gets .optional(), and one that is sometimes null gets .nullable().
Should I tighten the generated schema?
Usually, yes. The schema describes your example, so consider adding .email(), .url(), .int(), enums or .datetime() where you know more about the data.
Which Zod version is this for?
The output uses the core API (z.object, z.array, z.union, .optional, .nullable) that works in both Zod 3 and Zod 4.
Last updated