CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ajv

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

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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;

docs

core-validation.md

error-handling.md

index.md

jtd-schemas.md

keywords-vocabularies.md

schema-2019.md

schema-2020.md

schema-management.md

standalone-generation.md

typescript-integration.md

tile.json