Skip to content

Formatters & Code

JSON Schema → Zod / Valibot / ArkType

Three runtime-validator flavours from one JSON Schema.

Runs in your browser
JSON Schema · source
lines: 33chars: 460size: 460 B
Zod schema · result
lines: 11chars: 281size: 281 B
live

Understanding JSON Schema → Zod

Two ways to say the same shape — language-agnostic versus TypeScript-native.

What JSON Schema buys you, why Zod won on the frontend, and the gotchas when translating between them.

JSON Schema — the spec.

JSON Schema (draft 2020-12) is a JSON document that describes the shape of other JSON documents. It's language-agnostic — OpenAPI uses it for request bodies, AsyncAPI uses it for message payloads, AJV validates against it in any JS runtime, equivalent validators exist in Python, Go, Rust, Ruby. The runtime validation is its job; type generation tools (json-schema-to-typescript, datamodel-code-generator) turn it into static types.

Zod — TypeScript-native.

Zod (Colin McDonnell, 2020) is a TypeScript-first validation library where the schema is also the type. z.object({ name: z.string() }) defines both a runtime validator and a compile-time type. z.infer<typeof Schema>extracts the static type. No code generation, no separate .json file, no out-of-sync moments. Won the frontend ecosystem essentially overnight because of this single property.

The translation table.

JSON Schema "type": "string" → Zod z.string()."minLength": 3.min(3)."enum": ["a","b"] z.enum(["a","b"])."oneOf": [...] z.union([...])."type": "array", "items": {...} z.array(z.X())."properties": {...}, "required": [...] z.object({...})plus .optional() on non-required fields. The translation is straightforward for ~95 % of schemas.

The gotchas.

Refs. JSON Schema's $ref is hierarchical and can be circular; Zod uses lazy schemas with explicit recursion. Tuples. JSON Schema's tuple form (items as array) maps to z.tuple([...]), not z.array(). Additional properties. JSON Schema's "additionalProperties": false maps to Zod's.strict(). Format strings (date-time, email, uuid) map to Zod's named checks (.datetime(), .email(), .uuid()) but the definitions don't always agree on edge cases.

A worked translation.

JSON Schema: {"type":"object","properties":{"id":{"type":"string","format":"uuid"},"age":{"type":"integer","minimum":0}},"required":["id"]} → Zod: z.object({ id: z.string().uuid(), age: z.number().int().min(0).optional() }). One JSON object becomes one TS literal; the type inferred from it matches what a JSON Schema → TypeScript codegen tool would produce. The Zod version runs the validator at runtime for free.

object → z.object

schema → schema

Direct field-by-field translation.

properties + required + format → z.object + optional + .uuid

= Same shape, native TS

Which to keep on your boundary.

If your API has external consumers in many languages, keep JSON Schema as the source of truth; generate Zod (and TypeScript types) from it. If your API is TypeScript-only end-to-end (tRPC, Next.js server actions), keep Zod as the source of truth; generate JSON Schema from it for documentation. Don't try to maintain both by hand — they will drift, and the drift is exactly the bug you're trying to prevent.

Frequently asked questions

Quick answers.

Does this tool support JSON Schema drafts?

It supports most common features from Draft 4, 6, and 7. Complex features like logic-heavy `if/then/else` conditionals may require manual adjustment in the resulting code.

Why include Zod, Valibot, and ArkType?

Zod is the industry standard for its ecosystem support, while Valibot offers a smaller bundle size through modularity. ArkType prioritises performance using a specialised syntax engine.

Is my schema sent to a server?

No. The translation engine runs entirely within your browser session using local JavaScript execution. Your schemas and generated code never leave your device.

Can I convert nested objects and arrays?

Yes. The tool recursively traverses the schema to generate nested `z.object()`, `v.object()`, or scope definitions that match your original structure depth.

People also search for

Related tools

More in this room.

See all in Formatters & Code