React & TypeScript

JSON to TypeScript & Zod Schema

Paste any JSON sample and get back a strictly-typed TypeScript interface and a Zod validation schema. Toggle interface vs type, generate runtime-safe inputs for Server Actions and APIs.

Sample:

JSON input

Generated TypeScript types

export interface ProfileData {
  bio: string;
  avatarUrl: string;
  location: string;
  socials: SocialsData;
}

export interface SocialsData {
  twitter: string;
  github: string;
  website: string;
}

export interface PreferencesData {
  theme: string;
  locale: string;
  notifications: NotificationsData;
}

export interface NotificationsData {
  email: boolean;
  push: boolean;
  digest: string;
}

export interface RootObject {
  id: string;
  email: string;
  displayName: string;
  role: string;
  emailVerified: boolean;
  profile: ProfileData;
  preferences: PreferencesData;
  createdAt: string;
}
Advertisement

How to use

  1. 1Paste your JSON into the left pane, drop a .json file via the Upload button, or click one of the sample presets (User Profile, E-Commerce Product, Blog Post) to see real-world shapes.
  2. 2Set the Root Type Name (default: RootObject). The generator uses this as the exported interface / type / Zod schema identifier and as the basis for naming nested types.
  3. 3Pick TypeScript Types or Zod Schema. With TypeScript you can also toggle between "interface" and "type" declarations - both compile to the same runtime shape, but they read differently in your editor.
  4. 4Copy the result or download a .ts file. The Zod output is ready to drop into a Server Action, an API route handler, or a react-hook-form resolver.

Frequently asked questions

TypeScript interface vs type: which should I use?
They are functionally equivalent for object shapes: both give you editor autocomplete, structural typing, and compile to nothing at runtime. The differences are stylistic: interfaces are open to declaration merging (you can re-open an interface in another file and add fields), which is useful for plugin architectures and global augmentation. Type aliases are better for unions, intersections, mapped types, and primitives wrapped in a name. The React community has trended toward type for component props and interfaces for plain data shapes. The generator lets you pick whichever your team prefers; the output is identical at runtime.
Why do I need Zod if I already have TypeScript types?
TypeScript types are erased at compile time. They are a development-time tool that helps you and your editor, but at runtime the wire payload, the database row, the form input, and the env var are all untyped JavaScript values. Zod fills that gap: a Zod schema is a real value that can validate unknown input and throw a structured error if it does not match. The two complement each other - define a Zod schema once, then use z.infer<typeof schema> to derive the matching TypeScript type. You get runtime safety without writing the type by hand twice.
How do I use this with Next.js Server Actions?
Server Actions receive FormData or untyped arguments from the client, and the only way to reject malformed input before it reaches your business logic is to validate it. The pattern is: parse the input with a Zod schema at the top of the action, return a structured error object if validation fails, and only then run the database / API call. z.infer<typeof schema> gives you the fully-typed object for the rest of the function. This is the same pattern recommended in the Next.js docs for Server Action input validation.
How do I use this with API route handlers?
In a Next.js Route Handler (or any fetch handler), the request body is an untyped Promise. Read it with request.json(), pipe it through schema.safeParse, return a 400 with the issue list on failure, and use the typed data on success. For an external API you control neither, this is the difference between a robust service and one that crashes on the first unexpected field. Zod also lets you .transform() and .pipe() values (for example coercing a string id into a number) before they reach your code.
How does z.infer work for type inference?
z.infer<typeof schema> is a conditional type that walks the Zod schema at the type level and produces a TypeScript type with the same shape. The Zod schema is the single source of truth, and the type is derived. This means renaming a field, adding a default, or wrapping a value in z.optional() is automatically reflected in z.infer without you touching the type definition. It eliminates the bug class where the type and the runtime check drift apart over time.
What about circular references and recursive types?
The generator does not detect self-referential JSON shapes (for example a tree node with a children: Node[] field). For those cases, write the type by hand using a TypeScript interface with a self-reference, or use Zod with z.lazy(() => NodeSchema) to break the cycle. The tool targets the 95% case of straightforward JSON payloads - request / response bodies, database row shapes, configuration objects, where recursion is rare.
Can I trust the generated types to be 100% accurate?
No. Type inference from a single JSON sample can only describe the shape it has seen. A field that is a string in the sample might be a number on a different day; a field that is present in the sample might be missing in production. The generated types are an excellent starting point, but for production code you should still mark optional-looking fields as z.optional() and add z.string().email(), z.string().url(), z.number().int(), and other refinements that JSON alone cannot tell you about.

The Senior Full-Stack Production Kit (2026)

Checklists, Docker recipes, and SSR error fixes in one dense PDF.

Get Free Kit

Related articles