JSON to Zod Schema
Convert JSON to Zod TypeScript validation schema — nested objects, arrays, nullable fields
You received an API response and need to validate it at runtime with Zod, but writing the schema by hand for a deeply nested object is tedious. Paste the JSON and this tool generates the Zod schema automatically — nested objects, arrays, nulls, and union types included.
What Is Zod?
Zod is a TypeScript-first schema declaration and validation library. You define a schema once and Zod provides static type inference and runtime validation. It’s widely used with React Hook Form, tRPC, and Next.js API routes.
import { z } from "zod";
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string(),
role: z.string().nullable(),
});
type User = z.infer<typeof UserSchema>; // TypeScript type
const user = UserSchema.parse(data); // runtime validation
How the Conversion Works
The converter analyzes the JSON structure recursively:
- string →
z.string() - number →
z.number() - boolean →
z.boolean() - null →
z.null()(or marks field as.nullable()) - object →
z.object({ ... }) - array →
z.array(...)— element type inferred from first element - mixed arrays →
z.array(z.union([...])) - undefined / missing → marks field as
.optional()
After Conversion
The generated schema is a starting point. You’ll often want to add:
.min(),.max(),.email(),.url()validators for strings.int(),.positive(),.min()for numbers.optional()for fields that may not always be present in real responses- Custom error messages via
.describe()or.refine()
Frequently Asked Questions
Does the schema work if my API sometimes omits fields?
Add .optional() to fields that may be missing: z.string().optional(). For fields that can be null or missing, use .nullish() which is equivalent to .nullable().optional().
How does the converter handle arrays with mixed types?
If an array contains elements of different types, the converter generates z.union([...]) with the detected types. For empty arrays, it generates z.array(z.unknown()).
Can I generate TypeScript types from the schema?
Yes. Use type MyType = z.infer<typeof MySchema> after the schema definition. This provides static type checking identical to a hand-written interface.
What is the difference between z.null() and .nullable()?
z.null() is a schema that only accepts null. .nullable() is a modifier that accepts the original type OR null. Use .nullable() for fields that are normally a string/number but can be null.