JSON Schema Generator
Infer a production-ready JSON Schema from one or more JSON samples. Drafts 2020-12, 2019-09, 7, 6, 4 — with format detection, $defs extraction, AJV validation, and exports to YAML, TypeScript, and Zod. Runs entirely in your browser.
No Schema output yet.
Paste JSON on the left — the inferred schema and exports appear here as you type.
What it does
Multi-sample inference
Paste 2+ JSON samples and the engine unifies them: a property is marked required only if it appears in every sample, type conflicts emit oneOf/anyOf, and observed value ranges feed minimum/maximum/minLength constraints.
Five JSON Schema drafts
Switch between Draft 2020-12 (default), 2019-09, 7, 6, and 4. Output uses draft-appropriate keywords ($defs vs definitions, prefixItems vs items tuple, nullability via type arrays) so the schema is immediately valid against the chosen meta-schema.
Format & pattern detection
Strings are inspected for ISO 8601 date-time, date, time, duration, email, hostname, IPv4, IPv6, URI, UUID, and regex formats. Pattern detection catches hex colors, slugs, ISBN, and user-supplied regexes — only emitted when every observed value matches.
AJV validation built in
The Validation tab uses AJV (the de facto JSON Schema validator) to confirm every input sample passes the inferred schema. Errors are shown with JSON Pointer paths and the exact failing rule.
Exports for the whole stack
Download the schema as .json or .yaml, or convert to TypeScript interfaces and Zod schemas in one click — useful when seeding API contracts, validators, and type definitions from the same source of truth.
$defs extraction
Repeated structures (the same Address shape used in three places, for example) are content-hashed and promoted to $defs / definitions with $ref pointers. Threshold is configurable: never, when used 2+ times, or when used 3+ times.
Privacy by design
Inference runs in your browser — no upload, no server round-trip, no telemetry on JSON content. Large inputs are processed in a Web Worker so the UI stays responsive on payloads of several megabytes.
Shareable URL state
Click Share to encode samples and settings into a compressed URL hash (LZ-String). Anyone with the link sees the same input and inferred schema — no server storage involved.
How to use JSON Schema Generator
- 1Paste or upload your JSON
Drop a JSON file, paste into the editor, or fetch from a URL. To improve schema accuracy, add multiple samples that show real-world variation (an empty array, a record with optional fields populated, edge cases).
- 2Choose the JSON Schema draft
Default is Draft 2020-12. Switch to Draft 7 if your validator (e.g., older Java or Go ecosystems) does not yet support 2020-12, or to Draft 2019-09 for OpenAPI 3.1 compatibility.
- 3Tune the inference settings
Toggle additionalProperties, format detection, $defs extraction threshold, and enum detection cardinality. Strict mode marks every observed property required; Balanced (default) requires only properties present in all samples.
- 4Validate against your samples
Open the Validation tab to run AJV against each input sample. Any failures highlight the path and rule — useful when you tighten settings (e.g., enable additionalProperties: false) and want to confirm the schema still matches.
- 5Copy, download, or share
Export the schema as JSON or YAML, or generate TypeScript interfaces / Zod schemas with one click. The Share button creates a URL that encodes your samples and settings — open it anywhere to reproduce the result.
When to use this
API contract documentation
Capture two or three real response payloads from your service, paste them as samples, and use the inferred schema as the canonical contract in OpenAPI components or in code review.
Pipeline & ETL validation
Generate a schema from production data samples, then use it as a quality gate at ingestion to reject malformed records before they reach the warehouse.
TypeScript type seeding
Take an external API response, paste it, and export the TypeScript tab as the starting point for response interfaces — no need to handwrite types from a JSON dump.
Test fixture validation
Lock down the shape of test fixtures by inferring a schema from current passing fixtures, then run the schema against new fixtures in CI to catch accidental shape drift.
Common errors & fixes
- “Invalid JSON” when pasting copied data
- Trailing commas, single-quoted strings, and unquoted keys are JavaScript-only and not valid JSON. Either fix the source, or enable the JSON5 / JSONC toggle to accept those extensions.
- Required field is missing in the schema
- A property is required only if it appears in every sample. Add a sample that includes the field, or switch the strictness setting to Strict to mark every observed property required.
- Format keyword (e.g., email) is not detected
- Format detection is conservative — it emits the keyword only when every observed string matches. Add cleaner samples, or set the format manually after generation.
- AJV validation fails after a schema edit
- Manual edits to the output schema can introduce constraints stricter than the input. Click “Reset to inferred” to roll back, or relax the offending keyword (additionalProperties, minLength, format).
- Browser slows on a 10 MB input
- Inputs over 100 KB are processed in a Web Worker, but very large arrays use sample-based inference (first 200 + random 200 + last 100 items) for speed. Disable real-time mode in settings if your machine struggles.
Technical details
| Default draft | JSON Schema Draft 2020-12 |
| Supported drafts | 2020-12, 2019-09, 7, 6, 4 |
| Validator | AJV 8 with ajv-formats (lazy-loaded) |
| Max input size | 10 MB per sample (inputs > 100 KB use a Web Worker) |
| Format detection | date-time, date, time, duration, email, hostname, ipv4, ipv6, uri, uri-reference, uuid, regex |
| Pattern detection | hex color, slug, ISBN, ISSN, user-supplied regex |
| Exports | JSON, YAML, TypeScript interfaces, Zod schemas |
| Sharing | LZ-String compressed URL hash (no server storage) |
| Privacy | All processing in-browser; zero network requests for core flow |
JSON Schema vs TypeScript types — why both still matter in 2026
TypeScript types are a compile-time tool: they vanish at runtime. JSON Schema is a runtime contract: it is data that can be passed across services, embedded in OpenAPI documents, used to drive form generation, and validated against actual payloads. The two are complementary, not redundant.
When a backend Node.js service receives a request, TypeScript can guarantee that internal calls match types — but only after the request is parsed and trusted. The boundary between the network and the running process is exactly where JSON Schema (or Zod, which is essentially JSON-Schema-shaped) earns its keep: parse the body once, validate it against the schema, and only then hand the typed object to your business logic. Skipping that step turns TypeScript into theatre — the compiler thinks the data is `User` but the runtime received `null`.
This tool gives you both at once: infer JSON Schema for the runtime contract, then export TypeScript interfaces for the compile-time types. They stay in sync because they come from the same samples. If your codebase already uses Zod for validation-and-types in a single source, the Zod export does the same job with a different ergonomics tradeoff. The point is that TypeScript by itself is not validation, and that JSON Schema (or its equivalents) is what stops bad data from becoming bad behavior.
Draft 2020-12 vs Draft 7 — what actually changed
Most JSON Schema generators in the wild still emit Draft 7 because that is what their validator understood when they were written. Draft 2020-12 is the current published version and brings several improvements that matter when you are designing real schemas.
The biggest change is `prefixItems` for tuple-shaped arrays. In Draft 7 you wrote `items: [schema1, schema2]` to mean “the first item must match schema1 and the second must match schema2.” In 2020-12, that syntax was retired in favor of `prefixItems: [schema1, schema2]` with `items` reserved for the “rest” schema. The renaming clears up an ambiguity that confused validators and humans alike.
The `$defs` keyword (replacing the older `definitions`) is now part of the official vocabulary, which means tooling can reliably detect reusable subschemas without relying on convention. Boolean schemas (`true`/`false` as a complete schema) are formalized: `{ ...properties, additionalProperties: false }` and `{ ...properties, additionalProperties: { type: ... } }` work as you expect.
When should you stay on Draft 7? If your validator runtime cannot upgrade — for example, an older Java validator pinned to a specific dependency — you have to match that version. OpenAPI 3.1 aligns with Draft 2020-12; OpenAPI 3.0 uses a Draft 4-flavored subset. This generator targets 2020-12 by default but lets you switch with a single setting; the inference is the same, only the rendering changes.
Why multi-sample inference produces strictly better schemas
Inferring a schema from one sample is fast but always gets two things wrong. First, it cannot distinguish optional properties from required properties — every key in the sample looks required, even though many are not. Second, it cannot distinguish a constant value from a representative value — a single `"status": "active"` becomes `type: string` even when the real domain is an enum of three values.
Multi-sample inference fixes both. With three or more samples, a property is required only if it appears in every sample (intersection), so optional fields automatically end up outside the `required` array. With repeated values, the engine collects all observed values for each field and emits an `enum` when the cardinality is small (default ≤ 8). Type conflicts across samples — say, a field that is `string` in one sample and `null` in another — emit `oneOf` or `anyOf`, surfacing the union explicitly instead of silently picking one.
The practical advice: when you generate a schema for a real API, do not just paste the happiest example. Paste 3–5 representative payloads: an empty array, a record with optional fields populated, a record where a discriminated union takes a different branch, a record with a null where a value is allowed. The schema you get is one you can actually trust at the boundary of your service. A single-sample schema is a starting point; a multi-sample schema is a contract.
When to extract repeated subschemas as $defs
Inline schemas are easier to read at first glance; $defs schemas are easier to maintain. The right tradeoff depends on how often a subshape repeats and how likely it is to evolve.
If an Address shape appears once in a User object, leaving it inline is correct — extracting it adds indirection without simplifying anything. If the same Address shape appears in User, Order, and Invoice, extracting it once and using `{ "$ref": "#/$defs/Address" }` three times reduces duplication and ensures that when Address gains a `country_code` field, you update one place. The default threshold in this tool is 2+ uses; if you prefer a more conservative output, raise it to 3+.
There is a second consideration: the consumer of the schema. Some validators and codegen tools handle `$ref` flawlessly; some struggle with deeply nested or recursive `$ref`. If you are generating TypeScript via a codegen tool that does not support `$ref`, extraction will produce types you cannot consume — set the threshold to “never” and accept the duplication. The tool also automatically handles cycle detection: a schema that would otherwise refer to itself infinitely (a Tree node whose children are Tree nodes) becomes a `$ref` automatically, regardless of the threshold setting.
Format detection is conservative on purpose
The `format` keyword in JSON Schema is one of the most misused features. The spec says formats are advisory — validators may or may not enforce them — and the precise definition of each format varies. AJV with `ajv-formats` enforces a strict version of each: `email` follows RFC 5322 lite, `date-time` follows ISO 8601 / RFC 3339, `uuid` requires hyphenated lowercase. If your data does not match the strict spec, validation fails even though the data looks fine to a human.
The inference engine in this tool is conservative for exactly that reason. A format keyword is emitted only when every observed value of a property matches the strict format spec. One value with a typo, one value using a non-standard email shape (e.g., display-name notation), one date in `M/D/YYYY` rather than `YYYY-MM-DD`, and the format keyword is dropped — the property remains a plain string. This avoids the worst failure mode: a schema that AJV rejects against the same input it was generated from.
If you want a format that the engine refused to emit, set it manually after generation. The output editor accepts direct edits and revalidates against your samples in real time. If you also want to relax the strictness, switch to a draft (4 or 6) where many formats are not validated by default — but be aware that you are giving up the runtime guarantee in exchange for a more lenient schema.
Frequently Asked Questions
Does the JSON Schema Generator send my data anywhere?
- No. Parsing, inference, validation, and export all run in your browser. The only network call the page makes is fetching the page itself; even the optional URL-fetch action runs from your browser.
Which JSON Schema drafts are supported?
- Drafts 2020-12 (default), 2019-09, 7, 6, and 4. Output uses draft-appropriate keywords automatically: $defs vs definitions, prefixItems vs items tuple form, and the correct nullability syntax for each draft.
How does multi-sample inference work?
- Add 2+ JSON samples on separate tabs. The engine unifies them: a property is marked required only if it appears in every sample, types that vary across samples emit oneOf/anyOf, and observed value ranges feed minimum/maximum/minLength constraints. This produces a strictly better schema than inferring from a single example.
Why aren’t my email / uuid / date-time values detected as formats?
- Format detection only emits a format keyword when every observed string of that property matches. One non-matching value disables the format. Either fix the outlier sample or set the format manually after generation.
What is $defs extraction and when should I use it?
- $defs (or definitions in older drafts) lets you reuse a subschema by reference. The tool detects structurally identical subtrees and promotes them to $defs when they appear at or above your chosen threshold (default: 2+). It keeps the schema readable when the same shape (e.g., Address) appears in many places.
How accurate are the TypeScript and Zod exports?
- The exporters convert inferred JSON Schema directly to TypeScript interfaces and Zod schemas, including unions, optionals, arrays, and nested objects. Format keywords map to refinements where Zod supports them (e.g., z.string().email()). Anything not representable in TS/Zod (custom keywords, complex conditionals) is preserved with a comment.
Can I edit the generated schema?
- Yes. The output editor allows direct edits, with live AJV-based validation. The “Reset to inferred” button rolls back to the engine output if you want to start over.
How does the Share feature work?
- Share encodes your samples and settings using LZ-String compression and writes them to the URL hash. Open the URL in any browser and the same inputs and inferred schema are restored. Nothing is stored on a server, and very large inputs may exceed practical URL length — in that case, download the bundle as a JSON file instead.
Why did you choose AJV over a lighter validator?
- AJV is the most widely used JSON Schema validator in the JavaScript ecosystem, with mature support for all five drafts and the official format suite. It is loaded lazily — only when you open the Validation tab — so it does not affect initial page load.
Can I generate schemas from JSON5 or JSONC input?
- Yes — toggle JSON5 / JSONC mode on the input pane to allow trailing commas, single-quoted strings, and // comments. The output schema is always strict JSON.
Related Tools
JSON Formatter
Clean, minify, and validate JSON data structures.
JSON Validator
Validate JSON syntax and get precise error messages with line numbers. Check if JSON is well-formed instantly.
JSON ↔ CSV Converter
Convert JSON arrays to CSV and CSV back to JSON. Custom delimiter, header row control, and one-click download.
YAML Formatter
Format and validate YAML. Convert YAML to JSON or JSON to YAML. Supports 2 and 4 space indentation.
Regex Tester
Real-time expression matching and testing.