2kb vanilla JavaScript validation library with TypeScript and Standard Schema support.
The JavaScript validation library field is crowded. Why use validate.js over Valibot or Zod?
validate.js is vanilla JavaScript — drop this file in any JavaScript or TypeScript project and it will Just Work regardless of toolchain. You might use it if you're building a website without a bundler, if you're not using TypeScript or if you just want something small and vanilla.
Why not use validate.js? If you're building a Real Production Application, you probably already have package.json set up with a bundler, in which case you may as well use one of the larger libraries (as long as they tree shake to a small bundle size).
validate.js is not on npm; instead, it's meant to be vendored, or copied directly into your project's source code.
Don't be put off — validate.js a single 350 line file, of which only 150 lines are actually JavaScript code. It doesn't bite!
Easily validate complex types by using simple validators together:
import { parse, object, number, string } from "./validate.js";
const schema = object({
a: string,
b: number
});
const result = parse(schema, { a: "abc", b: 123 });If you're using TypeScript, validate.js is even more useful, statically narrowing the types of parsed objects:
import { parse, object, number, string } from "./validate.js";
const schema = object({
a: string,
b: number
});
const foo: unknown = { a: "abc", b: 123 };
const result = parse(schema, foo);
result; // { a: string; b: number }In fact, validate.js can do this even if you're using vanilla JavaScript! You can express almost the entire TypeScript type system in JSDoc comments, which means you can get the benefits of static type checking in normal JavaScript files. (That's how validate.js provides TypeScript support.)
import { parse, object, number, string } from "./validate.js";
const schema = object({
a: string,
b: number
});
/** @type {unknown} */
const foo = { a: "abc", b: 123 };
const result = parse(schema, foo);
result; // { a: string; b: number }validate.js conforms to Standard Schema, so you can use it anywhere you'd use another conformant validation library.
Validates a value against a schema. Returns the value on success, throws a SchemaError on failure.
import { parse, string } from "./validate.js";
parse(string, "hello"); // "hello"
parse(string, 42); // throws SchemaErrorValidates a value against a schema. Returns true or false.
import { is, string } from "./validate.js";
is(string, "hello"); // true
is(string, 42); // falseMatches booleans.
import { is, boolean } from "./validate.js";
is(boolean, false); // true
is(boolean, 0); // falseMatches numbers.
import { is, number } from "./validate.js";
is(number, 0); // true
is(number, "string"); // falseMatches strings.
import { is, string } from "./validate.js";
is(string, "test"); // true
is(string, true); // falseMatches bigints.
import { is, bigint } from "./validate.js";
is(bigint, 1n); // true
is(bigint, 1); // falseMatches symbols.
import { is, symbol } from "./validate.js";
is(symbol, Symbol()); // true
is(symbol, "string"); // falseMatches undefined.
import { is, undefined as undef } from "./validate.js";
is(undef, undefined); // true
is(undef, null); // falseMatches null.
import { is, null as nil } from "./validate.js";
is(nil, null); // true
is(nil, undefined); // falseMatches any value.
import { is, any } from "./validate.js";
is(any, "anything"); // trueMatches a specific value using strict equality.
import { is, literal } from "./validate.js";
const schema = literal(5);
is(schema, 5); // true
is(schema, 6); // falseValidates that a value is an object where each property matches the corresponding schema.
import { parse, object, number, string } from "./validate.js";
const schema = object({
name: string,
age: number
});
parse(schema, { name: "jake", age: 34 }); // { name: string; age: number }
parse(schema, { name: 34 }); // throwsValidates that all values in an object match the given schema.
import { parse, record, number } from "./validate.js";
const schema = record(number);
parse(schema, { a: 1, b: 2 }); // { [key: PropertyKey]: number }
parse(schema, { a: "one" }); // throwsValidates that all elements in an array match the given schema.
import { parse, array, number } from "./validate.js";
const schema = array(number);
parse(schema, [1, 2, 3]); // number[]
parse(schema, [1, "two"]); // throwsValidates that a value is an instance of the given constructor.
import { is, instance } from "./validate.js";
const schema = instance(Date);
is(schema, new Date()); // true
is(schema, {}); // falseMatches if the value matches any of the given schemata. Narrows to a union type.
import { parse, union, number, string } from "./validate.js";
const schema = union(number, string);
parse(schema, 0); // number | string
parse(schema, "one"); // number | string
parse(schema, false); // throwsMatches if the value matches all of the given schemata. Narrows to an intersection type.
import { parse, intersect, object, number, string } from "./validate.js";
const schema = intersect(
object({ a: number }),
object({ b: string })
);
parse(schema, { a: 1, b: "2" }); // { a: number } & { b: string }
parse(schema, { a: 1 }); // throwsMatches if the value matches the given schema or is undefined.
import { parse, optional, number } from "./validate.js";
const schema = optional(number);
parse(schema, 0); // number | undefined
parse(schema, undefined); // number | undefined
parse(schema, "string"); // throwsMatches if the value matches the given schema or is null.
import { parse, nullable, number } from "./validate.js";
const schema = nullable(number);
parse(schema, 0); // number | null
parse(schema, null); // number | null
parse(schema, "string"); // throwsCreates a schema from a type predicate and an error message function.
import { is, custom } from "./validate.js";
const email = custom(
(x): x is `${string}@${string}` =>
typeof x === "string" && x.includes("@"),
(x) => `Expected email, received \`${JSON.stringify(x)}\``
);
is(email, "user@example.com"); // true
is(email, "not-an-email"); // falseTypeScript utility type that extracts the output type from a schema.
import { object, number, string, InferOutput } from "./validate.js";
const schema = object({
name: string,
age: number
});
type Person = InferOutput<typeof schema>; // { name: string; age: number }