A fast and easy to use JSON Schema validator for JavaScript and Node.js through draft-07
npx @tessl/cli install tessl/npm-jsonschema@1.5.0jsonschema is a comprehensive JSON Schema validator for JavaScript and Node.js that supports JSON Schema draft-07. It provides both simple validation functions for quick usage and a full Validator class with advanced features including custom formats, custom keywords, schema dereferencing, error localization, and pre-validation hooks.
npm install jsonschemaconst { validate, Validator } = require('jsonschema');ES modules:
import { validate, Validator } from 'jsonschema';const { validate, Validator } = require('jsonschema');
// Simple validation
const result = validate(4, {"type": "number"});
console.log(result.valid); // true
// Advanced validation with schema references
const v = new Validator();
// Add referenced schema
const addressSchema = {
"id": "/SimpleAddress",
"type": "object",
"properties": {
"lines": {"type": "array", "items": {"type": "string"}},
"zip": {"type": "string"},
"city": {"type": "string"},
"country": {"type": "string"}
},
"required": ["country"]
};
const personSchema = {
"id": "/SimplePerson",
"type": "object",
"properties": {
"name": {"type": "string"},
"address": {"$ref": "/SimpleAddress"},
"votes": {"type": "integer", "minimum": 1}
}
};
v.addSchema(addressSchema, '/SimpleAddress');
const result = v.validate(person, personSchema);jsonschema is built around several key components:
validate function for basic validation needsQuick validation using the standalone validate function for basic use cases.
/**
* Validates an instance against a JSON schema
* @param instance - The data to validate
* @param schema - The JSON schema to validate against
* @param options - Optional validation options
* @returns ValidatorResult with validation status and errors
*/
function validate(instance: any, schema: any, options?: Options): ValidatorResult;Full-featured validator class with schema registry, custom formats, and extensible validation.
/**
* Advanced JSON Schema validator with schema registry and extensibility
*/
class Validator {
constructor();
/** Custom format validation functions */
customFormats: {[formatName: string]: CustomFormat};
/** Registry of loaded schemas */
schemas: {[id: string]: Schema};
/** Array of unresolved schema references */
unresolvedRefs: string[];
/** Custom validation attributes/keywords */
attributes: {[property: string]: CustomProperty};
/**
* Add a schema to the validator's registry
* @param schema - The schema to add
* @param uri - Optional URI for the schema
* @returns The added schema or void
*/
addSchema(schema?: Schema, uri?: string): Schema|void;
/**
* Validate an instance against a schema
* @param instance - The data to validate
* @param schema - The schema to validate against
* @param options - Validation options
* @param ctx - Schema context (internal use)
* @returns ValidatorResult with validation status and errors
*/
validate(instance: any, schema: Schema, options?: Options, ctx?: SchemaContext): ValidatorResult;
}Comprehensive result objects providing detailed validation status, errors, and metadata.
/**
* Result of a validation operation
*/
class ValidatorResult {
constructor(instance: any, schema: Schema, options: Options, ctx: SchemaContext);
/** The validated instance */
instance: any;
/** The schema used for validation */
schema: Schema;
/** Property path to the validated data */
propertyPath: string;
/** Array of validation errors */
errors: ValidationError[];
/** Whether validation succeeded */
valid: boolean;
/**
* Add a validation error to the result
* @param detail - Error message string or ErrorDetail object
* @returns The created ValidationError
*/
addError(detail: string|ErrorDetail): ValidationError;
/**
* String representation of the validation result
* @returns String describing the result
*/
toString(): string;
}
/**
* Individual validation error
*/
class ValidationError {
constructor(message?: string, instance?: any, schema?: Schema, propertyPath?: any, name?: string, argument?: any);
/** Array path to the error location */
path: (string|number)[];
/** String property path (e.g., "instance.foo.bar") */
property: string;
/** Human-readable error message */
message: string;
/** Schema that failed validation */
schema: string|Schema;
/** Instance value that failed */
instance: any;
/** Name of the failed validation keyword */
name: string;
/** Additional argument for the failed keyword */
argument: any;
/**
* String representation of the error
* @returns Formatted error message
*/
toString(): string;
}
/**
* Error thrown when using throwError options
*/
class ValidatorResultError extends Error {
/** The validated instance */
instance: any;
/** The schema used for validation */
schema: Schema;
/** Validation options used */
options: Options;
/** Validation errors that occurred */
errors: ValidationError;
}
/**
* Error thrown for invalid schemas
*/
class SchemaError extends Error {
constructor(msg: string, schema: Schema);
/** The invalid schema */
schema: Schema;
/** Error description */
message: string;
}Schema scanning, reference resolution, and registry management for complex schema relationships.
/**
* Scan a schema for references and sub-schemas
* @param base - Base URI for resolving references
* @param schema - Schema to scan
* @returns SchemaScanResult with found schemas and references
*/
function scan(base: string, schema: object): SchemaScanResult;
/**
* Result of schema scanning operation
*/
class SchemaScanResult {
constructor(found: any, ref: any);
/** Found schema ID */
id: any;
/** Schema reference */
ref: any;
}/**
* JSON Schema definition interface
*/
interface Schema {
$id?: string;
id?: string;
$schema?: string;
$ref?: string;
title?: string;
description?: string;
multipleOf?: number;
maximum?: number;
exclusiveMaximum?: number | boolean;
minimum?: number;
exclusiveMinimum?: number | boolean;
maxLength?: number;
minLength?: number;
pattern?: string | RegExp;
additionalItems?: boolean | Schema;
items?: Schema | Schema[];
contains?: Schema;
maxItems?: number;
minItems?: number;
uniqueItems?: boolean;
maxProperties?: number;
minProperties?: number;
required?: string[] | boolean;
propertyNames?: boolean | Schema;
additionalProperties?: boolean | Schema;
definitions?: {[name: string]: Schema};
properties?: {[name: string]: Schema};
patternProperties?: {[name: string]: Schema};
dependencies?: {[name: string]: Schema | string[]};
const?: any;
enum?: any[];
type?: string | string[];
format?: string;
allOf?: Schema[];
anyOf?: Schema[];
oneOf?: Schema[];
not?: Schema;
if?: Schema;
then?: Schema;
else?: Schema;
default?: any;
examples?: any[];
}
/**
* Validation options for customizing validation behavior
*/
interface Options {
/** Array of schema keywords to skip during validation */
skipAttributes?: string[];
/** Allow unknown schema keywords without throwing errors */
allowUnknownAttributes?: boolean;
/** Pre-validation hook function for property processing */
preValidateProperty?: PreValidatePropertyFunction;
/** Post-validation rewrite function for instance transformation */
rewrite?: RewriteFunction;
/** Base URI for resolving relative schema references */
base?: string;
/** Throw ValidationError on first validation failure */
throwError?: boolean;
/** Treat undefined values as validation failures */
required?: boolean;
/** Throw ValidatorResultError on first validation failure */
throwFirst?: boolean;
/** Throw ValidatorResultError after complete validation */
throwAll?: boolean;
/** Include nested errors from oneOf/anyOf validations */
nestedErrors?: boolean;
}
/**
* Post-validation rewrite function for transforming validated instances
*/
interface RewriteFunction {
(instance: any, schema: Schema, options: Options, ctx: SchemaContext): any;
}
/**
* Pre-validation property processing function
*/
interface PreValidatePropertyFunction {
(instance: any, key: string, schema: Schema, options: Options, ctx: SchemaContext): any;
}
/**
* Validation context passed to custom validators and hooks
*/
interface SchemaContext {
/** Current schema being validated */
schema: Schema;
/** Validation options in use */
options: Options;
/** Property path to current validation location */
propertyPath: string;
/** Base URI for schema resolution */
base: string;
/** Available schemas in the validator registry */
schemas: {[base: string]: Schema};
/** Function to create child validation contexts */
makeChild: (schema: Schema, key: string) => SchemaContext;
}
/**
* Custom format validation function
*/
interface CustomFormat {
(input: any): boolean;
}
/**
* Custom validation attribute/keyword function
*/
interface CustomProperty {
(instance: any, schema: Schema, options: Options, ctx: SchemaContext): string|ValidatorResult;
}
/**
* Error detail object for ValidationError constructor
*/
interface ErrorDetail {
/** Error message */
message: string;
/** Error name/type */
name: string;
/** Additional error data */
argument: string;
}const { Validator } = require('jsonschema');
// Add global custom format
Validator.prototype.customFormats.myFormat = function(input) {
return input === 'myFormat';
};
// Add instance-specific custom format
const validator = new Validator();
validator.customFormats.phoneNumber = function(input) {
return /^\d{3}-\d{3}-\d{4}$/.test(input);
};
const result = validator.validate('555-123-4567', {
type: 'string',
format: 'phoneNumber'
});const { Validator } = require('jsonschema');
const validator = new Validator();
// Add custom validation keyword
validator.attributes.contains = function validateContains(instance, schema, options, ctx) {
if(typeof instance !== 'string') return;
if(typeof schema.contains !== 'string') {
throw new Error('"contains" expects a string');
}
if(instance.indexOf(schema.contains) < 0) {
return 'does not contain the string ' + JSON.stringify(schema.contains);
}
};
const result = validator.validate("I am an instance", {
type: "string",
contains: "I am"
});const { Validator } = require('jsonschema');
const schema = {
properties: {
date: {id: 'http://example.com/date', type: 'string'},
},
};
const value = {
date: '2020-09-30T23:39:27.060Z',
};
function unmarshall(instance, schema) {
if(schema.id === 'http://example.com/date') {
return new Date(instance);
}
return instance;
}
const v = new Validator();
const res = v.validate(value, schema, {rewrite: unmarshall});
// res.instance.date is now a Date objectconst { Validator } = require('jsonschema');
const validator = new Validator();
// Throw on first error
try {
validator.validate("invalid", {type: "number"}, {throwFirst: true});
} catch (error) {
// error is ValidatorResultError
console.log(error.errors);
}
// Include nested errors from oneOf/anyOf
const schema = {
oneOf: [
{ type: 'string', minLength: 32, maxLength: 32 },
{ type: 'string', maxLength: 16 },
{ type: 'number' },
]
};
const result = validator.validate('This string is 28 chars long', schema, {
nestedErrors: true
});