Skip to main content
VestVest

Form validation that feels like writing tests

Write validation logic,
not boilerplate

A framework-agnostic library that separates your validation rules from your feature code.

npm i vest
Complex forms, simplified
import { create, test, enforce } from 'vest';

const suite = create((data = {}) => {
test('username', 'is required', () => {
enforce(data.username).isNotBlank();
});

test('username', 'already taken', async () => {
await doesUsernameExist(data.username);
});

test('password', 'must be 8+ chars', () => {
enforce(data.password).longerThan(7);
});
});

suite.run(formData);
Framework agnosticAsync ready
Vest looks and feels like a unit testing framework, but for your forms.
By separating validation logic from your UI, you get a system that handles async checks, dependent fields, and conditional logic without cluttering your component state.
Loading Editor...

Designed for the way you build

A complete toolkit for form sanity

Vest combines a familiar testing syntax with a smart, stateful core. It manages pending async tests, field focus, and strict type safety so you don't have to.

๐ŸงชFamiliar

Testing syntax

Write validations using test() and enforce() - declarative syntax you already know from Mocha or Jest.

๐ŸŒPortable

Use it anywhere

Framework agnostic. Works seamlessly with React, Vue, Svelte, or vanilla JS. Fully compatible with Standard Schema.

โšก๏ธResilient

Async by default

Handle server checks and promises natively. Vest tracks pending states and prevents race conditions automatically.

๐Ÿ“˜TypeScript

Fully typed

First-class TypeScript support. Define your data shape once and enjoy full type inference and autocomplete across your suite.

๐ŸชถLightweight

Zero external dependencies

Built on a modular architecture of internal micro-packages. No third-party bloat, no supply chain surprises.

๐Ÿง Stateful

Smart state

Vest remembers previous runs and merges results, allowing you to validate only the fields the user is interacting with.