FormatterHQ

JSON to Zod Schema Generator

Turn a JSON sample into Zod schemas with matching TypeScript types. Nested objects, arrays, optional fields and dates are inferred automatically.

Input JSON
Output TYPESCRIPT
Ready.

How to use the JSON to Zod Schema

  1. Paste your JSON sample (an object or an array of objects) into the Input editor, or use Sample, Upload file or Load URL.
  2. Set the Top-level class name; the root schema is called NameSchema and the inferred type Name.
  3. Press Generate; the schema updates as you edit the JSON.
  4. Use Copy or Download above the output panel to take the Zod schema with you.

JSON to Zod: generate a schema from a sample

Zod is a TypeScript-first validation library: you describe the shape of data once, and get both runtime validation and a static type through z.infer. Writing schemas for large API payloads by hand is tedious, so this JSON to Zod generator does the first draft for you. It infers types from a JSON sample with quicktype and prints one z.object schema per object shape, ordered so that every schema is defined before it is used.

Example

Input (class name Task):

{
  "id": 42,
  "title": "Write docs",
  "done": false,
  "priority": 2.5,
  "tags": ["docs"],
  "owner": { "name": "Ada", "email": null },
  "due": "2026-10-01T09:00:00Z",
  "subtasks": [
    { "title": "Outline", "estimate": 2 },
    { "title": "Draft" }
  ]
}
import * as z from "zod";

export const OwnerSchema = z.object({
    "name": z.string(),
    "email": z.null(),
});
export type Owner = z.infer<typeof OwnerSchema>;

export const SubtaskSchema = z.object({
    "title": z.string(),
    "estimate": z.number().optional(),
});
export type Subtask = z.infer<typeof SubtaskSchema>;

export const TaskSchema = z.object({
    "id": z.number(),
    "title": z.string(),
    "done": z.boolean(),
    "priority": z.number(),
    "tags": z.array(z.string()),
    "owner": OwnerSchema,
    "due": z.coerce.date(),
    "subtasks": z.array(SubtaskSchema),
});
export type Task = z.infer<typeof TaskSchema>;

Validate incoming data with TaskSchema.parse(data), which throws a ZodError describing every mismatch, or safeParse to get a result object instead.

How JSON maps to Zod

  • Strings, numbers and booleans become z.string(), z.number() and z.boolean(). Integers and decimals are both z.number(); add .int() yourself where it matters.
  • ISO date strings become z.coerce.date(), which converts the string into a Date during parsing.
  • Keys missing from some objects in an array get .optional().
  • Arrays become z.array(...); arrays with mixed element types use a union.
  • A value that is only ever null in the sample becomes z.null(); values that are sometimes null become a union such as z.union([z.null(), z.string()]), which you can shorten to z.string().nullable().

Refining the generated schema

A sample can only tell the generator what types values have, not what rules they follow. After generating, add constraints that document your API contract:

export const TaskSchema = z.object({
    id: z.number().int().positive(),
    title: z.string().min(1).max(200),
    done: z.boolean(),
    priority: z.number().min(0).max(5),
    tags: z.array(z.string()),
    owner: OwnerSchema,
    due: z.coerce.date(),
    subtasks: z.array(SubtaskSchema),
});

Other common edits: replace z.string() with z.enum(["open", "closed"]) for fields with a fixed set of values, use z.string().email() or .url() for formatted strings, and change a z.null() into z.string().nullable() when you know the field can hold text. By default z.object strips unknown keys; use .strict() if extra keys should be rejected.

Using the schema with fetch

const res = await fetch("/api/tasks/42");
const result = TaskSchema.safeParse(await res.json());
if (!result.success) {
    console.error(result.error.issues);
} else {
    const task: Task = result.data; // fully typed, dates already converted
}

Validating at the boundary like this means the rest of your code can trust the data's shape, and a changed API shows up as a clear validation error rather than an undefined property deep in your UI.

Zod versions

The output uses the import * as z from "zod" form and basic schema methods that work in Zod 3 and Zod 4. If your project pins an older major version, check the import style it expects.

If you only need static types, JSON to TypeScript produces plain interfaces. For language-neutral validation, JSON to JSON Schema generates a draft-06 JSON Schema. Format the result with the TypeScript Formatter. All generation happens in your browser.

Frequently asked questions

Does the generated Zod schema validate formats like email or UUID?
No. The generator only knows value types from your sample. Add refinements such as .email(), .uuid() or .min() by hand.
Why is a date field z.coerce.date()?
ISO 8601 strings are recognized as dates. z.coerce.date() converts them to Date objects during parsing. Use z.string() instead if you want to keep the raw string.
How do I get the TypeScript type?
Each schema is followed by an exported type created with z.infer, for example export type Task = z.infer<typeof TaskSchema>.
Does it work with Zod 4?
The output uses core schema methods available in both Zod 3 and Zod 4, so it works with either in most cases.
What happens to extra keys not in the schema?
z.object removes unknown keys when parsing. Add .strict() to reject them or .passthrough() to keep them.

Last updated October 3, 2026

Guides

Related tools

XML to C++ Generate C++ classes with nlohmann::json helpers from a XML sample instantly, with nested types detected automatically. XML to Crystal Generate Crystal classes with JSON mapping from a XML sample instantly, with nested types detected automatically. XML to C# Generate C# classes with JsonProperty attributes from a XML sample instantly, with nested types detected automatically. XML to Dart Generate Dart classes with fromJson and toJson from a XML sample instantly, with nested types detected automatically. XML to Elm Generate Elm type aliases with decoders from a XML sample instantly, with nested types detected automatically. XML to Flow Generate Flow Flow type definitions from a XML sample instantly, with nested types detected automatically. XML to Go Generate Go structs with json tags from a XML sample instantly, with nested types detected automatically. XML to Haskell Generate Haskell records with Aeson instances from a XML sample instantly, with nested types detected automatically. XML to Java Generate Java POJO classes with getters and setters from a XML sample instantly, with nested types detected automatically. XML to JavaScript PropTypes Generate JavaScript PropTypes React PropTypes definitions from a XML sample instantly, with nested types detected automatically. XML to JSON Schema Generate JSON Schema a JSON Schema document from a XML sample instantly, with nested types detected automatically. XML to Kotlin Generate Kotlin data classes from a XML sample instantly, with nested types detected automatically.