JSON tools

JSON to Zod Schema Generator

Paste JSON and get Zod schemas that validate it at runtime, plus the matching TypeScript types through z.infer.

  • Free foreverNo trial, no paywall, no usage limits.
  • No sign-upOpen the page and start. We never ask for an email to use a tool.
  • PrivateEverything runs in your browser. Your input is never uploaded or stored on our servers.
  • Works offlineOnce the page has loaded, the tool keeps working without a connection.

Zod options

Every option has a tooltip. Your choices are remembered on this device; your JSON never is.
Reset options to defaults
Name of the top-level type. If your JSON is an array, this names each item. Nested types are named after their keys.
The default, and what npm install zod installs: top-level formats such as z.email(), z.iso.datetime(), z.int(), z.strictObject().Method syntax such as z.string().email() and .strict(), for projects still on Zod 3. It also runs on Zod 4, which keeps these APIs.
Add export type X = z.infer<typeof XSchema> next to each schema, so the static type and the runtime check come from one source.
Strings that were ISO 8601 date-times in every sample get .datetime() (with offsets allowed when the sample had them).
Validate string formats every sample matched. Off by default: a sample can match by coincidence.
Use .int() where every sample was a whole number, so 1.5 is rejected.
Reject unknown keys instead of silently stripping them. Good for request bodies, risky for third-party responses.

JSON sample

Paste a real response. Arrays are treated as samples: keys missing from some items become optional, null values nullable.
Clear

Zod schema

CopyDownload schema.ts
Paste JSON or load the example. Code is generated in your browser as you type.

Need this built into your own API or pipeline? Talk to our team

Quick answer

A Zod schema validates data at runtime and gives you its TypeScript type for free through z.infer. Paste a JSON sample into Playxoft's free JSON to Zod generator to get a schema for every object: missing keys become .optional(), null values become .nullable(), whole numbers get .int(), and ISO dates get date-time validation. Choose Zod 3 or Zod 4 syntax, then call parse or safeParse on untrusted data.

  • Zod 3 and Zod 4 syntax
  • z.infer type exports
  • Optional, nullable, nullish
  • Integer and date-time checks
  • Email, URL and UUID formats
  • Dependency-ordered schemas
  • Download schema.ts

How to use the JSON to Zod

  1. 1Paste a real API response into JSON sample.
  2. 2Name the root schema with Root type name: User becomes UserSchema and type User.
  3. 3Keep Zod 4 (the default) or pick Zod 3, and toggle Validate dates, Integers, Emails, URLs, UUIDs and Strict objects.
  4. 4Copy the code or download schema.ts, and install Zod with npm install zod (which installs Zod 4).
  5. 5Validate data with UserSchema.safeParse(data) and handle the failure case.

Why use Zod instead of plain TypeScript types?

TypeScript checks your code, not your data. An interface for an API response is a promise the compiler can't verify, because the response only exists at runtime. Zod closes that gap: you describe the shape once, Zod validates real data against it, and z.infer derives the static type, so the type and the check can never drift apart.

import { z } from "zod";

// Zod 4. In Zod 3: z.number().int(), z.string().email(), z.string().datetime()
const UserSchema = z.object({
  id: z.int(),
  email: z.email(),
  createdAt: z.iso.datetime(),
});
type User = z.infer<typeof UserSchema>;

const user = UserSchema.parse(await res.json()); // typed and checked

Use it wherever untrusted data enters your program: fetch responses, form input, webhooks, message queues, environment variables and localStorage.

How does JSON map to Zod?

JSON in your sampleZod 3Zod 4
Stringz.string()z.string()
ISO 8601 date-timez.string().datetime()z.iso.datetime()
Whole numberz.number().int()z.int()
Decimal numberz.number()z.number()
Booleanz.boolean()z.boolean()
Arrayz.array(T)z.array(T)
Objectz.object({...})z.object({...})
Empty or ID-keyed objectz.record(z.string(), T)z.record(z.string(), T)
Mixed value typesz.union([A, B])z.union([A, B])

Schemas are written in dependency order, so each one is declared before another schema uses it, and every schema gets a matching export type. When a date-time in your sample carries a UTC offset such as +05:30, the generator adds { offset: true }, because by default Zod only accepts the Z suffix.

optional, nullable or nullish: what's the difference?

ModifierAcceptsGenerated when
.optional()The value, or a missing keyThe key is missing from some samples
.nullable()The value, or nullThe value is null in some samples
.nullish()The value, null or a missing keyBoth of the above

Choose these deliberately. An API that sends "middleName": null and one that leaves middleName out are different contracts, and Zod rejects the one you didn't declare. That is exactly what you want from a validator: a clear error at the boundary instead of an undefined deep inside your app.

What changed in Zod 4?

Zod 4, released in 2025, keeps the familiar API but moves string formats to the top level and tightens a few defaults. The generator writes this style by default:

  • z.email(), z.url(), z.uuid() and z.iso.datetime() replace z.string().email() and friends, which still work but are deprecated.
  • z.int() only accepts safe integers, so an ID above 2^53 fails validation. The generator falls back to z.number() for such fields, in both versions.
  • z.strictObject() and z.looseObject() replace the .strict() and .passthrough() methods.

Choose Zod 3 for a project still on Zod 3, or for shared code that must run on both: the Zod 3 syntax this generator writes runs on both major versions. Either way, z.object() strips unknown keys from the parsed result by default; turn on Strict objects to reject them instead.

How should I handle validation errors?

parse() throws a ZodError, while safeParse() returns a result you branch on, which keeps control flow explicit:

const result = UserSchema.safeParse(data);
if (!result.success) {
  console.error(result.error.issues); // each issue has a path and a message
  return;
}
const user = result.data; // fully typed

Each issue carries a path to the failing field, which maps straight onto form fields and log messages. Form libraries such as React Hook Form (through @hookform/resolvers) and API frameworks such as tRPC accept Zod schemas directly. Need plain types without runtime checks? The JSON to TypeScript generator writes interfaces from the same sample.

Frequently asked questions

Yes. By default z.object() strips keys it doesn't know from the parsed result without failing. Turn on Strict objects to reject unknown keys instead, which suits request bodies you control better than third-party responses.
Zod's date-time check accepts only UTC times ending in Z by default. If any date in your sample had an offset such as +05:30, the generator allows offsets so the schema accepts your real data.
Integers above 2^53 can't be stored exactly in a JavaScript number, so JSON.parse has already rounded them and Zod 4's integer check rejects them. Ask the API to send such IDs as strings and validate them with z.string().
Yes. React Hook Form accepts Zod schemas through the zodResolver in @hookform/resolvers, and tRPC procedures take Zod schemas as input validators. Both infer TypeScript types from the schema.
Zod 4 is the default, because npm install zod now installs it and its top-level formats are shorter and tree-shakable. Choose Zod 3 for a project still on Zod 3 or for code that must run on both versions; Zod 4 still accepts the Zod 3 syntax this generator writes, though it marks the method forms as deprecated.
Validate the JSON as it arrives, then rename the keys in a transform step, for example z.object({ user_id: z.number() }).transform((u) => ({ userId: u.user_id })). The schema still checks the original keys, and the inferred output type uses camelCase.

Last updated by the Playxoft engineering team.

From the engineers who built this tool

Fighting messy data every day?

When payloads, schemas and integrations keep breaking, the fix is usually upstream. We design typed APIs and backends that stay clean as you grow. Tell us what you are building and we will suggest the simplest architecture that fits.