Developers & Technical · Guide · Developer Utilities
How to write JSON schemas
Validate any data structure by writing clear JSON Schemas. Learn core keywords and composition for free with an instant online guide; no sign-up or download is needed.
JSON Schema is how you describe the shape of JSON data so machines can validate it, humans can understand it, and APIs can generate docs and clients from it. Write a schema once and you get validation, auto-completion, fixture generation, and contract tests for free. This guide covers the core keywords (type, properties, required, additionalProperties), the composition patterns (allOf, oneOf, $ref), how drafts differ, when to reach for JSON Schema vs alternatives (OpenAPI, Zod, TypeBox), and the common mistakes that let invalid data slip through.
Advertisement
A minimal schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer", "minimum": 0 }
},
"required": ["name"]
}This validates: {"name":"Alice","age":30} ✓
Rejects: {"age":30} (missing name), {"name":"Alice","age":-1} (negative age).
Core types
string, number, integer, boolean, null, object, array. integer rejects 1.5 where number accepts it.
Union: "type": ["string", "null"] for fields that can be nullable.
String constraints
minLength / maxLength: character bounds.
pattern: regex the string must match.
format: email, uri, date-time, uuid, hostname. Formats are informational by default; enable format validation to enforce.
enum: whitelist of allowed values — "enum": ["draft","published","archived"].
Number constraints
minimum / maximum: inclusive bounds.
exclusiveMinimum / exclusiveMaximum: non-inclusive bounds.
multipleOf: divisor check. Useful for cents (multipleOf: 0.01) or step sizes.
Object constraints
properties: map of key → sub-schema.
required: array of keys that must be present. Absent in required means optional.
additionalProperties: controls unknown keys. false rejects any key not listed; a schema object validates extra keys against that schema.
patternProperties: match property names by regex, apply sub-schema to values.
minProperties / maxProperties: count bounds.
Array constraints
items: schema every element must match.
prefixItems (draft 2020-12): tuple mode — first element matches first schema, second matches second, etc.
minItems / maxItems: length bounds.
uniqueItems: enforce no duplicates.
contains: at least one item must match this schema.
Composition
allOf: value must match every sub-schema. Useful for extending a base schema.
oneOf: exactly one sub-schema must match. Common for discriminated unions.
anyOf: at least one sub-schema must match.
not: negation — value must NOT match the sub-schema.
$ref — reusable pieces
{
"$defs": {
"Address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" }
},
"required": ["street","city"]
}
},
"type": "object",
"properties": {
"shipping": { "$ref": "#/$defs/Address" },
"billing": { "$ref": "#/$defs/Address" }
}
}Definitions live in $defs; $ref points at them with a JSON Pointer.
Drafts matter
Draft 4: widely supported. Uses definitions, not $defs. Older API tooling often stuck here.
Draft 7: common default. Added if/then/else, readOnly, writeOnly.
2019-09: $defs replaces definitions. Recursive refs cleaned up.
2020-12: prefixItems for tuples. Cleaner array validation.
Rule: always declare $schema so validators pick the right version.
Conditional schemas — if/then/else
{
"type": "object",
"properties": { "kind": { "enum": ["user","admin"] }},
"if": { "properties": { "kind": { "const": "admin" }}},
"then": { "required": ["permissions"] }
}If kind === "admin", permissions becomes required. Otherwise no extra constraint.
JSON Schema vs alternatives
OpenAPI: uses JSON Schema under the hood (with some extensions). Use OpenAPI for HTTP APIs where you want paths, responses, and auth all in one doc.
TypeScript interfaces: great for compile-time, useless at runtime. You need a runtime validator either way.
Zod / Yup / Joi (JS ecosystem): nicer DX, schema-as-code. Good for forms and internal validation. Export to JSON Schema when you need interop.
Protobuf / Avro: when you need binary efficiency and strict schema evolution rules, not JSON.
Tooling
Validators: ajv (JS, fastest), jsonschema (Python), go-jsonschema (Go).
Doc generators: json-schema-to-markdown, Redocly, Stoplight.
Code generators: json-schema-to-typescript, quicktype, datamodel-code-generator (Python Pydantic).
IDE integration: VS Code auto-validates JSON files against a matching schema. Huge productivity win for config files.
Common mistakes
Forgetting additionalProperties: false. Default is to allow unknown keys silently. Breaks contract testing.
Using type: number when you mean integer. Floats sneak through.
Missing required. Without required, every property is optional. Easy to miss on required fields.
Mixing drafts. $defs in draft 7 doesn’t work; definitions in 2020-12 doesn’t work (well, it’s allowed but unused).
Overly permissive enum. "enum": ["A", "a"] accepts both. Decide on case-sensitivity.
No format validation. format: email is a hint, not an enforced check unless you enable format mode in the validator.
Run the numbers
Generate a starter schema from sample JSON with the JSON schema generator. Pair with the JSON formatter to tidy your sample first, and the JSON to TypeScript converter to get types for your codebase.
Use these while you read
Tools that pair with this guide
- JSON Schema GeneratorCreate a draft-07 schema with types and required fields from any JSON instantly in your browser—free tool with no sign-up or download.Developer Utilities
- JSON FormatterPaste JSON to beautify, validate, and minify with clear error messages, all in your browser without sign-up—free instant tool for developers.Developer Utilities
- JSON to TypeScript InterfacePaste JSON to get matching TypeScript types with optional and nullable fields in seconds—free online tool, no sign-up or download needed.Developer Utilities
- JSON to CSV ConverterTurn JSON arrays into CSV with auto-detected headers and nested field flattening instantly in your browser—free, no-sign-up converter.Developer Utilities
Advertisement
Continue reading
- Developers & TechnicalGitHub Actions Without Being a DevOps ExpertMaster GitHub Actions for the 90% use case with this practical playbook. Build, test, and deploy instantly using free common templates and no-sign-up guides.
- Developers & TechnicalBest Practices for Building Developer ToolsLearn CI/CD, IDE, and documentation standards for paid dev tools instantly. Implement best practices for what companies actually buy online.
- Developers & TechnicalHow to Contribute to Open Source Developer ToolsFind beginner-friendly OSS projects and ship your first pull request with confidence. Free, instant playbook to avoid mistakes and scale contributions.
- Developers & TechnicalHow to Design CLI Tools Developers LoveFree guide to build CLI tools developers actually love: composability, sensible defaults, human errors, trust by default, predictability, fast feedback.
- Developers & TechnicalPassword Security Guide with Real Entropy ExamplesCalculate real password entropy with 2026 attacker speeds. Free guide to diceware passphrases, password managers, and 2FA based on actual attack vectors.
- Developers & TechnicalJSON Format Rules Every Developer Should KnowFree guide to strict JSON spec rules, JSON5 vs JSONC, top 10 parser errors, Schema validation, streaming huge files, and security: prototype pollution.