npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

livr

v2.13.3

Published

Lightweight validator supporting Language Independent Validation Rules Specification (LIVR 2.0 and LIVR 2.5)

Readme

LIVR Validator

Validation rules that are just data. The fastest JavaScript validator in the benchmarks, also when rules are built at runtime, with TypeScript types inferred from the schema and zero dependencies.

npm version npm downloads TypeScript Bundle Size Known Vulnerabilities

Documentation

The full documentation is at js.livr-spec.org:

  • Getting started: install, the first validator, errors and types
  • Custom rules: aliases, rule functions and their types
  • TypeScript: type inference and strict mode
  • API: Validator and AsyncValidator, their options and methods, registering rules
  • LIVR specification: the rules and the test suite shared by all implementations

The guides, the API and the TypeScript guide are also in the package, in node_modules/livr/docs. For AI assistants: llms.txt, and the whole documentation in one file, llms-full.txt.


Why LIVR

Rules are just data. A schema is a plain JSON structure, not code. Store it in a database, send it over the wire, share it with services written in other languages, build it at runtime, and load it safely even from untrusted sources: LIVR never turns a schema into code. Why schemas as data →

Incredible performance, also for rules built at runtime. The fastest in the benchmarks against Valibot, Zod, fastest-validator, Ajv and Joi. Most validators are fast only when a schema is compiled once; when rules come from a database, differ per tenant or come from a form builder, every call needs a new validator. There LIVR is tens to hundreds of times faster than Zod, fastest-validator and Ajv, and needs less than a microsecond to create a validator and validate a form. Benchmarks →

Type inference. TypeScript infers the type of the validated data from the schema itself: required and optional fields, literal unions from one_of, nested objects, lists and your own rules. No second definition to keep in sync. How it works →

Zero dependencies. Nothing to audit but LIVR itself. About 2 KB for the core, 5 KB with the 35 rules of LIVR 2.0 and 13 KB with all 68 built-in rules, min+gzip, and it runs in Node.js, browsers and edge runtimes. Why zero dependencies →

Proven. Maintained since 2013 and built on the LIVR specification (it implements LIVR 2.0 and LIVR 2.5), whose shared test suite collects edge cases found in implementations in 11 languages. More →

Also: error codes shaped like your data, validation and transformation in one pass, aliases and custom rules, and a sync and an async validator. The design decisions explain why LIVR works the way it does.


Installation

npm install livr

Works in Node.js and, through any bundler or an ESM CDN like https://esm.sh/livr, in browsers.

Quick Start

import LIVR from 'livr';

const validator = new LIVR.Validator({
  name: 'required',
  email: ['required', 'email'],
  age: 'positive_integer',
  password: ['required', { min_length: 8 }],
  password2: { equal_to_field: 'password' },
});

const validData = validator.validate(userData);

if (validData) {
  saveUser(validData); // validated data, fields without rules removed
} else {
  console.log(validator.getErrors());
  // { email: 'WRONG_EMAIL', password: 'TOO_SHORT' }
}

With TypeScript, the type comes from the schema:

import LIVR from 'livr';
import type { InferFromSchema } from 'livr/types';

const schema = {
  name: ['required', 'string'],
  age: 'positive_integer',
  role: { one_of: ['admin', 'user'] },
} as const;

type User = InferFromSchema<typeof schema>;
// { name: string; age?: number; role?: 'admin' | 'user' }

const validator = new LIVR.Validator<User>(schema);

In a new project, turn on strict mode: a misspelled rule or a rule without a type is a compile error then, instead of the unknown type. It is off by default, so existing projects keep compiling: turn it on there once every custom rule has a type.

// livr-options.ts: the import makes the file a module and loads the types of livr
import type {} from 'livr/types/inference';

declare module 'livr/types/inference' {
  interface TypeOptions {
    strictRules: true;
  }
}

Next: usage guide (modifiers, async validation, smaller bundles), custom rules, API reference.

Custom Rules

An alias gives a set of existing rules a name and an error code. A rule function gets the rule arguments and returns a function that checks one value: it returns an error code, or nothing when the value is valid. With TypeScript, declare the type of every custom rule and alias in RuleTypes, the type of the value after the rule: registering a rule does not give it a type.

import LIVR from 'livr';
import type { InferFromSchema } from 'livr/types';
import type { As, AliasType } from 'livr/types/inference';

// An alias: 'phone' in a schema runs 'string' and 'like', with an error code of its own
const phoneRules = ['string', { like: '^\\+?[0-9]{10,15}$' }] as const;
LIVR.Validator.registerAliasedDefaultRule({
  name: 'phone',
  rules: phoneRules,
  error: 'WRONG_PHONE',
});

// A rule function: { starts_with: 'SKU-' } calls starts_with('SKU-') once, when a validator
// compiles its rules, and the function it returns checks each value
LIVR.Validator.registerDefaultRules({
  starts_with(prefix: string) {
    return (value: unknown) => {
      if (LIVR.util.isNoValue(value)) return undefined; // empty values are the job of 'required'
      if (typeof value !== 'string' || !value.startsWith(prefix)) return 'WRONG_PREFIX';
      return undefined;
    };
  },
});

// The types, in any .ts file of the project with an import or an export
declare module 'livr/types/inference' {
  interface RuleTypes {
    phone: AliasType<typeof phoneRules>;
    starts_with: As<string>; // checks a string, `startsWith` gets the type too
  }
}

const schema = {
  phone: ['required', 'phone'],
  sku: { starts_with: 'SKU-' },
} as const;

type Product = InferFromSchema<typeof schema>; // { phone: string; sku?: string }

See the types in the TypeScript Playground. The function a rule returns gets (value, allValues, outputArr): push a value to outputArr to change the output. validator.registerRules() and validator.registerAliasedRule() register rules for one validator, and rules of AsyncValidator (livr/async) can return a promise.

More: the custom rules guide, types of rules with arguments, meta rules and rule packages in the TypeScript guide, and strict mode, which makes a misspelled rule or a rule without a type a compile error. In the package: docs/guide/custom-rules.md and docs/TYPESCRIPT.md.


Built-in Rules

livr implements LIVR 2.0 and LIVR 2.5: every rule of both versions is built in.

| Category | Rules | |----------|-------| | Common | required · not_empty · not_empty_list · any_object · required_if2.5 · any2.5 · boolean2.5 | | String | string · eq · one_of · max_length · min_length · length_between · length_equal · like · not_one_of2.5 · digits2.5 · starts_with2.5 · ends_with2.5 · contains2.5 | | Numeric | integer · positive_integer · decimal · positive_decimal · max_number · min_number · number_between · max_decimals2.5 | | Special | email · url · iso_date ({ min, max }2.5) · iso_datetime2.5 · iso_time2.5 · equal_to_field | | Meta | nested_object · variable_object · list_of · list_of_objects · list_of_different_objects · or · when2.5 · values2.5 · keys2.5 | | List2.5 | list_length · unique | | Format2.5 | uuid · ip · cidr · hostname · base64 · hex · digest · mongo_id · hex_color · mac · e164 · semver · jwt | | Checksum2.5 | luhn · credit_card · iban | | Modifiers | trim · to_lc · to_uc · remove · leave_only · default · split2.5 |

Rules and categories marked 2.5 were added in LIVR 2.5 and are loaded on first use. Implementations of LIVR 2.0 in other languages do not have them. The rules page shows the TypeScript type of every rule.

Need more rules? Check out livr-extra-rules for additional validators.


Contributing

Found a bug or have a feature request? Please open an issue on GitHub. The documentation site is built from docs/.


License

MIT License - see LICENSE for details.


Author

Viktor Turskyi (@koorchik)

Contributors

  • eNdiD