JSON Schema is the foundation of JSON Forms. It defines the structure of your data, the types of fields, and validation rules. JSON Forms supports both JSON Schema Draft 4 and Draft 7.
What is JSON Schema?
JSON Schema is a vocabulary that allows you to annotate and validate JSON documents. In JSON Forms, it serves as the single source of truth for:
Data structure and types
Validation rules
Default values
Metadata (titles, descriptions)
Type System
JSON Schema supports these primitive types:
type ?: string | string [];
String
{
"type" : "string" ,
"minLength" : 3 ,
"maxLength" : 50 ,
"pattern" : "^[A-Za-z]+$" ,
"description" : "Please enter your name"
}
Validation properties:
minLength, maxLength - Length constraints
pattern - Regular expression
format - Predefined formats (email, uri, date, time, etc.)
Number and Integer
{
"type" : "integer" ,
"minimum" : 1 ,
"maximum" : 100 ,
"multipleOf" : 5 ,
"default" : 50
}
Validation properties:
minimum, maximum - Value bounds
exclusiveMinimum, exclusiveMaximum - Exclusive bounds
multipleOf - Value must be a multiple of this number
Boolean
{
"type" : "boolean" ,
"default" : false
}
Object
{
"type" : "object" ,
"properties" : {
"name" : { "type" : "string" },
"age" : { "type" : "integer" }
},
"required" : [ "name" ],
"additionalProperties" : false
}
Validation properties:
properties - Property definitions
required - Required property names
additionalProperties - Allow/disallow extra properties
minProperties, maxProperties - Number of properties
Array
{
"type" : "array" ,
"items" : {
"type" : "string"
},
"minItems" : 1 ,
"maxItems" : 10 ,
"uniqueItems" : true
}
Validation properties:
items - Schema for array elements
minItems, maxItems - Array length
uniqueItems - Ensure all items are unique
Enumerations
Simple Enum
{
"type" : "string" ,
"enum" : [ "red" , "green" , "blue" ]
}
OneOf Enum (with labels)
{
"type" : "string" ,
"oneOf" : [
{ "const" : "de" , "title" : "Germany" },
{ "const" : "us" , "title" : "United States" },
{ "const" : "jp" , "title" : "Japan" }
]
}
oneOf enums allow you to provide human-readable labels for enum values using the title property.
JSON Schema defines standard formats for strings:
{
"type" : "string" ,
"format" : "email"
}
Common formats:
date - Full date (e.g., 2024-03-15)
time - Time (e.g., 14:30:00)
date-time - Date and time (ISO 8601)
email - Email address
uri - URI/URL
ipv4, ipv6 - IP addresses
Combining Schemas
JSON Schema provides powerful composition keywords:
allOf
All schemas must match:
{
"allOf" : [
{ "type" : "object" , "properties" : { "name" : { "type" : "string" } } },
{ "type" : "object" , "properties" : { "age" : { "type" : "integer" } } }
]
}
anyOf
At least one schema must match:
{
"anyOf" : [
{ "type" : "string" },
{ "type" : "number" }
]
}
oneOf
Exactly one schema must match:
{
"oneOf" : [
{ "type" : "object" , "properties" : { "credit_card" : { "type" : "string" } } },
{ "type" : "object" , "properties" : { "paypal" : { "type" : "string" } } }
]
}
References
Use $ref to reuse schema definitions:
{
"definitions" : {
"address" : {
"type" : "object" ,
"properties" : {
"street" : { "type" : "string" },
"city" : { "type" : "string" }
}
}
},
"type" : "object" ,
"properties" : {
"billingAddress" : { "$ref" : "#/definitions/address" },
"shippingAddress" : { "$ref" : "#/definitions/address" }
}
}
Complete Example
Here’s a real-world example from the JSON Forms codebase:
{
"type" : "object" ,
"properties" : {
"name" : {
"type" : "string" ,
"minLength" : 3 ,
"description" : "Please enter your name"
},
"vegetarian" : {
"type" : "boolean"
},
"birthDate" : {
"type" : "string" ,
"format" : "date" ,
"description" : "Please enter your birth date."
},
"nationality" : {
"type" : "string" ,
"enum" : [ "DE" , "IT" , "JP" , "US" , "RU" , "Other" ]
},
"personalData" : {
"type" : "object" ,
"properties" : {
"age" : {
"type" : "integer" ,
"description" : "Please enter your age."
},
"height" : {
"type" : "number"
},
"drivingSkill" : {
"type" : "number" ,
"maximum" : 10 ,
"minimum" : 1 ,
"default" : 7
}
},
"required" : [ "age" , "height" ]
}
},
"required" : [ "name" , "nationality" ]
}
JSON Schema in TypeScript
JSON Forms provides TypeScript types for JSON Schema:
import { JsonSchema7 } from '@jsonforms/core' ;
const schema : JsonSchema7 = {
type: 'object' ,
properties: {
name: {
type: 'string' ,
minLength: 3
}
}
};
JSON Schema 7
JSON Schema 4
export interface JsonSchema7 {
$ref ?: string ;
$id ?: string ;
$schema ?: string ;
title ?: string ;
description ?: string ;
default ?: any ;
// Type
type ?: string | string [];
// String validation
maxLength ?: number ;
minLength ?: number ;
pattern ?: string ;
// Number validation
multipleOf ?: number ;
maximum ?: number ;
exclusiveMaximum ?: number ;
minimum ?: number ;
exclusiveMinimum ?: number ;
// Object validation
properties ?: { [ property : string ] : JsonSchema7 };
required ?: string [];
additionalProperties ?: boolean | JsonSchema7 ;
// Array validation
items ?: JsonSchema7 | JsonSchema7 [];
minItems ?: number ;
maxItems ?: number ;
uniqueItems ?: boolean ;
// Enum
enum ?: any [];
const ?: any ;
// Combining schemas
allOf ?: JsonSchema7 [];
anyOf ?: JsonSchema7 [];
oneOf ?: JsonSchema7 [];
not ?: JsonSchema7 ;
// Format
format ?: string ;
}
JSON Forms also supports JSON Schema Draft 4 through the JsonSchema4 type.
Schema Resolution
JSON Forms resolves schemas internally when processing scopes:
// From packages/core/src/testers/testers.ts:124
let currentDataSchema = schema ;
if ( hasType ( schema , 'object' )) {
currentDataSchema = resolveSchema (
schema ,
schemaPath ,
context ?. rootSchema
);
}
This allows JSON Forms to:
Follow $ref pointers
Navigate through nested schemas
Resolve allOf, anyOf, oneOf combinations
The root schema is always available in the tester context to resolve references.
Validation
JSON Forms uses AJV (Another JSON Validator) to validate data against the schema:
// Compiled validator
const validator = ajv . compile ( schema );
// Validate data
const errors = validate ( validator , data );
Validation happens automatically:
When data changes
When the schema changes
On user input (depending on validation mode)
See the Data Binding section for more details on validation.
Best Practices
Use descriptive titles and descriptions
{
"type" : "string" ,
"title" : "Full Name" ,
"description" : "Enter your legal first and last name"
}
Titles and descriptions help users understand what each field is for.
{
"type" : "integer" ,
"default" : 18 ,
"minimum" : 0 ,
"maximum" : 150
}
Defaults improve user experience by pre-filling common values.
Use format for common data types
Keep schemas DRY with $ref
{
"definitions" : {
"contact" : { "type" : "string" , "format" : "email" }
},
"properties" : {
"email" : { "$ref" : "#/definitions/contact" },
"backupEmail" : { "$ref" : "#/definitions/contact" }
}
}
Reuse schema definitions to avoid duplication.
Next Steps
UI Schema Learn how to control the layout and presentation of your forms
Renderers Understand how JSON Forms selects renderers based on schema