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

  1. Enter json input and root type name.
  2. The result appears straight away and updates as you edit.
  3. 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.