or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-validation.mderror-handling.mdindex.mdjtd-schemas.mdkeywords-vocabularies.mdschema-2019.mdschema-2020.mdschema-management.mdstandalone-generation.mdtypescript-integration.md
tile.json

tessl/npm-ajv

Another JSON Schema Validator - high-performance JSON Schema validator for JavaScript and TypeScript

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/ajv@8.17.x

To install, run

npx @tessl/cli install tessl/npm-ajv@8.17.0

index.mddocs/

Ajv

Ajv (Another JSON Schema Validator) is a high-performance JSON Schema validator for JavaScript and TypeScript. It implements JSON Schema draft-04/06/07/2019-09/2020-12 standards and JSON Type Definition (JTD) RFC8927, generating optimized validation functions through code compilation for exceptional performance in Node.js and browsers.

Package Information

  • Package Name: ajv
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install ajv

Core Imports

import Ajv from "ajv";
import type {
  Schema,
  ValidateFunction,
  ErrorObject,
  Options,
  JSONSchemaType,
  JTDSchemaType
} from "ajv";

For specific JSON Schema versions:

import {Ajv2019} from "ajv/dist/2019.js";
import {Ajv2020} from "ajv/dist/2020.js";
import {Ajv as AjvJTD} from "ajv/dist/jtd.js";

For standalone code generation:

import standaloneCode from "ajv/dist/standalone";

For additional utilities:

import {ValidationError, MissingRefError} from "ajv";

CommonJS:

const Ajv = require("ajv");
const {ValidationError, MissingRefError} = require("ajv");

Basic Usage

import Ajv from "ajv";

// Create validator instance
const ajv = new Ajv();

// Add schema
const schema = {
  type: "object",
  properties: {
    foo: { type: "integer" },
    bar: { type: "string" }
  },
  required: ["foo"],
  additionalProperties: false
};

// Compile validation function
const validate = ajv.compile(schema);

// Validate data
const data = { foo: 1, bar: "abc" };
const valid = validate(data);

if (!valid) {
  console.log(validate.errors);
}

Architecture

Ajv is built around several key components:

  • Schema Classes: Multiple classes for different JSON Schema versions (Draft 7, 2019-09, 2020-12) and JTD
  • Compilation Engine: Code generation system that produces optimized validation functions
  • Keyword System: Extensible keyword and vocabulary system for custom validation logic
  • Type System: Full TypeScript integration with schema-to-type inference
  • Format System: Built-in and custom format validators for strings
  • Error Reporting: Detailed validation error objects with path information

Capabilities

Core Schema Validation

Primary JSON Schema validation functionality supporting Draft 7 schemas with discriminator support. Ideal for API validation, configuration validation, and data processing pipelines.

class Ajv extends AjvCore {
  constructor(options?: Options);
  
  errors?: ErrorObject[] | null;
  
  validate<T>(schema: Schema | string, data: unknown): data is T;
  validate(schemaKeyRef: AnySchema | string, data: unknown): boolean | Promise<unknown>;
  
  compile<T>(schema: Schema, meta?: boolean): ValidateFunction<T>;
  compileAsync<T>(schema: AnySchemaObject, meta?: boolean): Promise<AnyValidateFunction<T>>;
  
  addSchema(schema: AnySchema | AnySchema[], key?: string, meta?: boolean, validateSchema?: boolean): Ajv;
  addMetaSchema(schema: AnySchemaObject, key?: string, validateSchema?: boolean): Ajv;
  removeSchema(schemaKeyRef?: AnySchema | string | RegExp): Ajv;
  getSchema<T>(keyRef: string): AnyValidateFunction<T> | undefined;
  validateSchema(schema: AnySchema, throwOrLogError?: boolean): boolean | Promise<unknown>;
  
  addKeyword(kwdOrDef: string | KeywordDefinition, def?: KeywordDefinition): Ajv;
  removeKeyword(keyword: string): Ajv;
  getKeyword(keyword: string): AddedKeywordDefinition | boolean;
  addVocabulary(definitions: Vocabulary): Ajv;
  addFormat(name: string, format: Format): Ajv;
  
  errorsText(errors?: ErrorObject[] | null, options?: ErrorsTextOptions): string;
}

type AnyValidateFunction<T = any> = ValidateFunction<T> | AsyncValidateFunction<T>;

Core Validation

JSON Schema 2019-09 Support

Enhanced validation for JSON Schema Draft 2019-09 with dynamic references, unevaluated properties/items, and next generation features.

class Ajv2019 extends AjvCore {
  constructor(options?: Options);
  
  validate<T>(schema: Schema, data: unknown): data is T;
  compile<T>(schema: Schema): ValidateFunction<T>;
  compileAsync<T>(schema: AnySchema, meta?: boolean): Promise<AnyValidateFunction<T>>;
}

2019-09 Schemas

JSON Schema 2020-12 Support

Latest JSON Schema Draft 2020-12 validation with all modern features and improvements.

class Ajv2020 extends AjvCore {
  constructor(options?: Options);
  
  validate<T>(schema: Schema, data: unknown): data is T;
  compile<T>(schema: Schema): ValidateFunction<T>;
  compileAsync<T>(schema: AnySchema, meta?: boolean): Promise<AnyValidateFunction<T>>;
}

2020-12 Schemas

JSON Type Definition (JTD)

JTD schema validation with built-in serialization and parsing capabilities for high-performance data processing.

class Ajv extends AjvCore {
  constructor(options?: JTDOptions);
  
  validate<T>(schema: Schema, data: unknown): data is T;
  compile<T>(schema: Schema): ValidateFunction<T>;
  compileSerializer<T>(schema: SchemaObject): (data: T) => string;
  compileParser<T>(schema: SchemaObject): JTDParser<T>;
}

interface JTDParser<T> {
  (json: string): T | undefined;
  message?: string;
  position?: number;
}

type JTDOptions = CurrentOptions & {
  strict?: never;
  allowMatchingProperties?: never;
  allowUnionTypes?: never;
  validateFormats?: never;
  $data?: never;
  verbose?: boolean;
  $comment?: never;
  formats?: never;
  loadSchema?: never;
  useDefaults?: never;
  coerceTypes?: never;
  next?: never;
  unevaluated?: never;
  dynamicRef?: never;
  meta?: boolean;
  defaultMeta?: never;
  inlineRefs?: boolean;
  loopRequired?: never;
  multipleOfPrecision?: never;
};

JTD Schemas

Schema Management

Comprehensive schema management for adding, removing, and organizing schemas with support for references and meta-schemas.

interface SchemaManagement {
  addSchema(schema: AnySchema | AnySchema[], key?: string, meta?: boolean, validateSchema?: boolean): Ajv;
  addMetaSchema(schema: AnySchemaObject, key?: string, validateSchema?: boolean): Ajv;
  removeSchema(schemaKeyRef?: AnySchema | string | RegExp): Ajv;
  getSchema<T>(keyRef: string): AnyValidateFunction<T> | undefined;
  validateSchema(schema: AnySchema, throwOrLogError?: boolean): boolean | Promise<unknown>;
}

Schema Management

Custom Keywords and Vocabularies

Extensible keyword system for creating custom validation logic, format validators, and vocabulary extensions.

interface KeywordSystem {
  addKeyword(kwdOrDef: string | KeywordDefinition, def?: KeywordDefinition): Ajv;
  removeKeyword(keyword: string): Ajv;
  getKeyword(keyword: string): AddedKeywordDefinition | boolean;
  addVocabulary(definitions: Vocabulary): Ajv;
  addFormat(name: string, format: Format): Ajv;
}

Keywords and Vocabularies

TypeScript Integration

Advanced TypeScript integration with schema-to-type inference and compile-time type checking.

type JSONSchemaType<T> = 
  (T extends string ? {
    type: "string";
    enum?: readonly T[];
    const?: T;
    pattern?: string;
    minLength?: number;
    maxLength?: number;
    format?: string;
  } :
  T extends number ? {
    type: "number" | "integer";
    enum?: readonly T[];
    const?: T;
    multipleOf?: number;
    minimum?: number;
    maximum?: number;
    exclusiveMinimum?: number;
    exclusiveMaximum?: number;
  } :
  T extends boolean ? {
    type: "boolean";
    const?: T;
  } :
  T extends readonly (infer U)[] ? {
    type: "array";
    items?: JSONSchemaType<U>;
    minItems?: number;
    maxItems?: number;
    uniqueItems?: boolean;
    contains?: JSONSchemaType<U>;
  } :
  T extends Record<string, any> ? {
    type: "object";
    properties?: {[K in keyof T]?: JSONSchemaType<T[K]>};
    patternProperties?: Record<string, JSONSchemaType<any>>;
    additionalProperties?: JSONSchemaType<any> | boolean;
    required?: readonly (keyof T)[];
    minProperties?: number;
    maxProperties?: number;
    dependencies?: {[K in keyof T]?: JSONSchemaType<any> | readonly string[]};
    propertyNames?: JSONSchemaType<string>;
  } :
  T extends null ? {
    type: "null";
    const?: null;
  } :
  never) & {
    $id?: string;
    $schema?: string;
    $ref?: string;
    $comment?: string;
    title?: string;
    description?: string;
    default?: T;
    examples?: readonly T[];
    nullable?: boolean;
    discriminator?: {
      propertyName: string;
      mapping?: Record<string, string>;
    };
    readOnly?: boolean;
    writeOnly?: boolean;
    allOf?: readonly JSONSchemaType<T>[];
    anyOf?: readonly JSONSchemaType<T>[];
    oneOf?: readonly JSONSchemaType<T>[];
    not?: JSONSchemaType<T>;
    if?: JSONSchemaType<T>;
    then?: JSONSchemaType<T>;
    else?: JSONSchemaType<T>;
  };

type JTDSchemaType<T, D = Record<string, never>> = (
  | (T extends string
      ? { type: "string" }
      : T extends number
      ? { type: "float64" | "float32" | "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32" }
      : T extends boolean
      ? { type: "boolean" }
      : T extends readonly (infer U)[]
      ? U extends string
        ? { elements: { type: "string" } }
        : U extends number
        ? { elements: { type: "float64" | "float32" | "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32" } }
        : U extends boolean
        ? { elements: { type: "boolean" } }
        : { elements: JTDSchemaType<U, D> }
      : T extends Record<string, any>
      ? {
          properties: { [K in keyof T]: JTDSchemaType<T[K], D> };
        } & ({
          additionalProperties: true;
        } | {
          optionalProperties?: { [K in keyof T]?: JTDSchemaType<T[K], D> };
        })
      : never)
  | { enum: readonly T[] }
  | { ref: keyof D }
) & {
  nullable?: boolean;
  metadata?: Record<string, any>;
  definitions?: { [K in keyof D]: JTDSchemaType<D[K], D> };
};

type SomeJTDSchemaType = JTDSchemaType<any, Record<string, any>>;
type JTDDataType<S> = S extends JTDSchemaType<infer T> ? T : never;

TypeScript Integration

Error Handling and Reporting

Comprehensive error reporting system with detailed validation error information and customizable formatting.

interface ErrorObject<K extends string = string, P = Record<string, any>, S = unknown> {
  keyword: K;
  instancePath: string;
  schemaPath: string;
  params: P;
  propertyName?: string;
  message?: string;
  schema?: S;
  parentSchema?: AnySchemaObject;
  data?: unknown;
}

type ErrorNoParams<K extends string, S = unknown> = ErrorObject<K, Record<string, never>, S>;

interface ErrorsTextOptions {
  separator?: string;
  dataVar?: string;
}

function errorsText(errors?: ErrorObject[] | null, options?: ErrorsTextOptions): string;

class ValidationError extends Error {
  errors: ErrorObject[];
  ajv: true;
  validation: true;
  constructor(errors: ErrorObject[]);
}

class MissingRefError extends Error {
  readonly missingRef: string;
  readonly missingSchema: string;
  constructor(resolver: UriResolver, baseId: string, ref: string, msg?: string);
}

Error Handling

Standalone Code Generation

Generate standalone validation functions that don't require the Ajv runtime for deployment optimization.

function standaloneCode(
  ajv: Ajv,
  refsOrFunc?: {[K in string]?: string} | AnyValidateFunction
): string;

Standalone Code Generation

Core Types

interface Options extends CurrentOptions, DeprecatedOptions {}

interface CurrentOptions {
  // strict mode options
  strict?: boolean | "log";
  strictSchema?: boolean | "log";
  strictNumbers?: boolean | "log";
  strictTypes?: boolean | "log";
  strictTuples?: boolean | "log";
  strictRequired?: boolean | "log";
  allowMatchingProperties?: boolean;
  allowUnionTypes?: boolean;
  validateFormats?: boolean;
  
  // validation and reporting options
  $data?: boolean;
  allErrors?: boolean;
  verbose?: boolean;
  discriminator?: boolean;
  unicodeRegExp?: boolean;
  timestamp?: "string" | "date";
  parseDate?: boolean;
  allowDate?: boolean;
  specialNumbers?: "fast" | "null";
  $comment?: true | ((comment: string, schemaPath?: string, rootSchema?: AnySchemaObject) => unknown);
  formats?: {[Name in string]?: Format};
  keywords?: Vocabulary;
  schemas?: AnySchema[] | {[Key in string]?: AnySchema};
  logger?: Logger | false;
  loadSchema?: (uri: string) => Promise<AnySchemaObject>;
  
  // options to modify validated data
  removeAdditional?: boolean | "all" | "failing";
  useDefaults?: boolean | "empty";
  coerceTypes?: boolean | "array";
  
  // advanced options
  next?: boolean;
  unevaluated?: boolean;
  dynamicRef?: boolean;
  schemaId?: "id" | "$id";
  jtd?: boolean;
  meta?: SchemaObject | boolean;
  defaultMeta?: string | AnySchemaObject;
  validateSchema?: boolean | "log";
  addUsedSchema?: boolean;
  inlineRefs?: boolean | number;
  passContext?: boolean;
  loopRequired?: number;
  loopEnum?: number;
  ownProperties?: boolean;
  multipleOfPrecision?: number;
  int32range?: boolean;
  messages?: boolean;
  code?: CodeOptions;
  uriResolver?: UriResolver;
}

interface DeprecatedOptions {
  /** @deprecated */
  ignoreKeywordsWithRef?: boolean;
  /** @deprecated */
  jsPropertySyntax?: boolean;
  /** @deprecated */
  unicode?: boolean;
}

interface CodeOptions {
  es5?: boolean;
  esm?: boolean;
  lines?: boolean;
  optimize?: boolean | number;
  formats?: Code;
  source?: boolean;
  process?: (code: string, schema?: SchemaEnv) => string;
  regExp?: RegExpEngine;
}

interface Logger {
  log(...args: unknown[]): unknown;
  warn(...args: unknown[]): unknown;
  error(...args: unknown[]): unknown;
}

interface Plugin<Opts> {
  (ajv: Ajv, options?: Opts): Ajv;
  [prop: string]: any;
}

type Schema = SchemaObject | boolean;

interface SchemaObject { $id?: string; $schema?: string; $ref?: string; $comment?: string;

// Type keywords type?: JSONType | JSONType[]; enum?: any[]; const?: any;

// Numeric keywords multipleOf?: number; maximum?: number; exclusiveMaximum?: number; minimum?: number; exclusiveMinimum?: number;

// String keywords maxLength?: number; minLength?: number; pattern?: string; format?: string;

// Array keywords items?: AnySchema | AnySchema[]; additionalItems?: AnySchema; maxItems?: number; minItems?: number; uniqueItems?: boolean; contains?: AnySchema;

// Object keywords maxProperties?: number; minProperties?: number; required?: string[]; additionalProperties?: AnySchema; properties?: {[key: string]: AnySchema}; patternProperties?: {[key: string]: AnySchema}; propertyNames?: AnySchema; dependencies?: {[key: string]: AnySchema | string[]};

// Boolean logic keywords allOf?: AnySchema[]; anyOf?: AnySchema[]; oneOf?: AnySchema[]; not?: AnySchema;

// Conditional keywords if?: AnySchema; then?: AnySchema; else?: AnySchema; }

type JSONType = "string" | "number" | "integer" | "boolean" | "object" | "array" | "null";

interface UriResolver { parse(uri: string): URIComponent; resolve(base: string, path: string): string; serialize(component: URIComponent): string; }

interface RegExpEngine { (pattern: string, u: string): RegExpLike; code: string; }

interface RegExpLike { test: (s: string) => boolean; }

type Format = AddedFormat | string;

type AddedFormat = | true | RegExp | FormatValidator<string> | FormatDefinition<string> | FormatDefinition<number> | AsyncFormatDefinition<string> | AsyncFormatDefinition<number>;

type FormatValidator<T extends string | number> = (data: T) => boolean;

interface FormatDefinition<T extends string | number> { type?: T extends string ? "string" | undefined : "number"; validate: FormatValidator<T> | (T extends string ? string | RegExp : never); async?: false | undefined; compare?: FormatCompare<T>; }

interface AsyncFormatDefinition<T extends string | number> { type?: T extends string ? "string" | undefined : "number"; validate: AsyncFormatValidator<T>; async: true; compare?: FormatCompare<T>; }

type AsyncFormatValidator<T extends string | number> = (data: T) => Promise<boolean>; type FormatCompare<T extends string | number> = (data1: T, data2: T) => number | undefined;

type Vocabulary = (KeywordDefinition | string)[];

interface KeywordDefinition { keyword: string | string[]; type?: JSONType | JSONType[]; schemaType?: JSONType | JSONType[]; allowUndefined?: boolean; $data?: boolean; implements?: string[]; before?: string; post?: boolean; metaSchema?: AnySchemaObject; validateSchema?: AnyValidateFunction; dependencies?: string[]; error?: KeywordErrorDefinition; $dataError?: KeywordErrorDefinition; }

type AddedKeywordDefinition = KeywordDefinition & { type: JSONType[]; schemaType: JSONType[]; };

interface KeywordErrorDefinition { message: string | ((cxt: KeywordErrorCxt) => string); params?: ((cxt: KeywordErrorCxt) => any); }

interface KeywordErrorCxt { gen: CodeGen; keyword: string; data: Name; $data?: string | false; schema: any; parentSchema?: AnySchemaObject; schemaCode: any; schemaValue: any; schemaType?: JSONType[]; errsCount?: Name; params: {[P in string]?: any}; it: SchemaCxt; }

type AnySchema = Schema | AsyncSchema; type AnySchemaObject = SchemaObject | AsyncSchema; type SchemaMap = {[Key in string]?: AnySchema};

interface AsyncSchema extends SchemaObject { $async: true; }

interface ValidateFunction<T = unknown> { (data: unknown): data is T; errors?: ErrorObject[] | null; evaluated?: Evaluated; schema: AnySchema; schemaEnv: SchemaEnv; source?: SourceCode; }

interface AsyncValidateFunction<T = unknown> extends ValidateFunction<T> { (data: unknown): Promise<T>; $async: true; }

type AnyValidateFunction<T = any> = ValidateFunction<T> | AsyncValidateFunction<T>;

interface Evaluated { props?: EvaluatedProperties; items?: EvaluatedItems; dynamicProps: boolean; dynamicItems: boolean; }

type EvaluatedProperties = {[K in string]?: true} | true; type EvaluatedItems = number | true;