JSON to Zod schema

free

Generate a runtime-validated Zod schema with z.infer type aliases.

Schema accepts sample
JSON
385 chars · 385 BValid
Zod
import { z } from "zod";

export const AddressSchema = z.object({
  street: z.string(),
  city: z.string(),
  country: z.string(),
  postalCode: z.string(),
});

export type Address = z.infer<typeof AddressSchema>;

export const RootSchema = z.object({
  id: z.string().uuid(),
  name: z.string(),
  email: z.string().email(),
  age: z.number().int(),
  bio: z.null(),
  address: AddressSchema,
  tags: z.array(z.string()),
  createdAt: z.string().datetime({ offset: true }),
  verified: z.boolean(),
});

export type Root = z.infer<typeof RootSchema>;

export const rootSchema = RootSchema;
592 chars · 592 B

Generate a Zod schema from any JSON sample, complete with `z.infer` type aliases so you get a runtime validator and the matching TypeScript type from one declaration. Built on the same schema IR as the JSON → TypeScript tool, so nested optionals, structural dedup, and format-aware string detection all carry over — UUID fields emit `.uuid()`, ISO timestamps emit `.datetime({ offset: true })`, emails emit `.email()`.

Common use cases

  • Validating API responses at runtime. Drop in a representative payload, paste the schema into your fetcher, and wrap each response in `schema.parse()` for end-to-end type safety with runtime guarantees.
  • tRPC / Hono / Next.js route handlers. Use the generated schema as the `input` / `output` for tRPC procedures or Hono validators. The `z.infer` aliases give you the matching TypeScript type for handlers and clients.
  • Form data validation. Pair with `react-hook-form` + `@hookform/resolvers/zod` to get form validation that matches your backend schema exactly.
  • Configuration file parsing. Load `config.json` with `schema.parse(JSON.parse(file))` to catch malformed config at startup with a precise error path instead of failing at first use.

Frequently asked

What Zod version is the output compatible with?

Zod v3+. The emitter avoids v4-only constructs and stays on the stable subset that hasn't moved in the last two majors.

Should I turn on `.strict()`?

Turn it on if you want extra (unknown) keys in the input to fail validation. Useful for closed-world configs and API contracts; leave off for forward-compatible APIs where new fields are expected.

Why is my date field a `z.string().datetime()` instead of `z.date()`?

JSON has no date type — values come through as strings. `z.string().datetime()` validates the ISO 8601 format. If you want a `Date` instance after parsing, chain `.transform((s) => new Date(s))`.

Can I disable the format refinements?

Yes — flip the 'Format refinements' switch off. The output becomes plain `z.string()` for every string field, useful when you don't want stricter validation than your data actually provides.

Why do I see both `UserSchema` and `userSchema`?

PascalCase schema constants follow the type names; the lower-case alias matches your chosen schema name. They reference the same value — keep whichever fits your codebase convention.

Does the URL save my options?

Yes — root name, strict mode, and refinements are all encoded as query parameters for shareable links.