JSON to Zod schema
Validate API data at runtime and get the matching TypeScript type from a single definition.
Loading the tool…
Processing and privacy: The result is calculated inside your browser and your data is not sent to any server.
How to use it
- Enter json input and root type name.
- The result appears straight away and updates as you edit.
- Copy the result, or copy a link that keeps the same values to share it.
How it is calculated
z.string(), z.number(), z.number().int(), z.boolean(), z.array() and z.unknown(), with a separate schema per nested object declared before use. .nullable() for null values and .optional() for keys missing from some items, then the type is exported with z.infer.
Example
Inputs: Root type name = Root. Result: Generated code: import { z } from "zod"; const OrderSchema = z.object({ order_id: z.string(), total: z.number(), coupon: z.string().nullable(), }); const AddressSchema = z.object({ city: z.string(), postal_code: z.string(), }); export const RootSchema = z.object({ id: z.number().int(), name: z.string(), email: z.string(), is_active: z.boolean(), balance: z.number(), tags: z.array(z.string()), address: AddressSchema, orders: z.array(OrderSchema), }); export type Root = z.infer<typeof RootSchema>;; Types generated: 3; Fields: 13.
{
"id": 1024,
"name": "Sara Ahmed",
"email": "sara@example.com",
"is_active": true,
"balance": 1520.75,
"tags": ["vip", "riyadh"],
"address": { "city": "Riyadh", "postal_code": "12211" },
"orders": [
{ "order_id": "A-1", "total": 99.5, "coupon": "EID10" },
{ "order_id": "A-2", "total": 120, "coupon": null }
]
}import { z } from "zod";
const OrderSchema = z.object({
order_id: z.string(),
total: z.number(),
coupon: z.string().nullable(),
});
const AddressSchema = z.object({
city: z.string(),
postal_code: z.string(),
});
export const RootSchema = z.object({
id: z.number().int(),
name: z.string(),
email: z.string(),
is_active: z.boolean(),
balance: z.number(),
tags: z.array(z.string()),
address: AddressSchema,
orders: z.array(OrderSchema),
});
export type Root = z.infer<typeof RootSchema>;Limits and caveats
- It uses only the core functions shared by Zod 3 and Zod 4.
- It adds no refinements such as .email() or .min(); add them to fit your data rules.
Questions about this tool
Why are the nested schemas declared first?
A JavaScript constant must be declared before use, so each nested schema comes before the schema that uses it.
How do I validate data?
Use RootSchema.parse(data) to throw on a mismatch, or safeParse to get a result without an exception.
Is my JSON sent to a server?
No. The conversion runs in your browser and the JSON never leaves your device.
