Registry / serialization / vest
library0.0.15jsnpmunverified

Vest is a declarative and framework-agnostic JavaScript validation framework that enables developers to write validation logic using a syntax familiar to unit testing frameworks like Jest or Mocha. It aims to separate validation concerns from UI logic, promoting cleaner components and easier testing. Currently stable at version 6.3.2, Vest offers robust features including asynchronous validation support, strong TypeScript type safety, server-side rendering (SSR) compatibility with state hydration, and extensibility for custom rules. It distinguishes itself by managing validation state intelligently, handling dependent fields, and providing a powerful assertion library (`enforce`). The project maintains a consistent release cadence with regular patch and minor updates, and significant architectural shifts between major versions. Vest is designed for complex validation scenarios across various JavaScript environments (React, Vue, Svelte, Angular, Node.js, vanilla JS) and implements the Standard Schema specification.

npm install vest
INSTALL
IMPORT
SIG · VEST
V
vest
serializationjavascriptv0.0.15
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

create
import { create } from 'vest';
const create = require('vest');
Vest is primarily designed for ESM. CommonJS `require` can be problematic since v4 deprecated default exports and v6 returns a Suite Object, not a function.
test
import { test } from 'vest';
import vest, { test } from 'vest';
Since Vest v4, default imports were removed for better tree-shaking. Always use named imports for core utilities like `test`.
enforce
import { enforce } from 'vest';
const { enforce } = require('vest');
The `enforce` assertion library is a named export. Ensure your environment supports ESM imports.
memo
import { memo } from 'vest/memo';
The `memo` utility, for memoizing validation logic, was moved to its own module in v6.
SuiteSerializer
import { SuiteSerializer } from 'vest/exports/SuiteSerializer';
For SSR and hydration, `SuiteSerializer` is imported from a specific subpath.

This quickstart demonstrates how to define a Vest validation suite with synchronous and asynchronous tests, including conditional logic, and how to execute the suite and interpret its results for a typical signup form.

import { create, test, enforce } from 'vest'; // Simulate an async API call, e.g., checking if a username exists const doesUsernameExist = async (username: string): Promise<boolean> => { return new Promise(resolve => { setTimeout(() => { resolve(username === 'admin'); // 'admin' is taken }, 500); }); }; interface FormData { username?: string; email?: string; password?: string; confirmPassword?: string; } const signupSuite = create((data: FormData = {}) => { test('username', 'Username is required', () => { enforce(data.username).isNotBlank(); }); test('username', 'Username must be at least 3 characters long', () => { enforce(data.username).longerThanOrEquals(3); }); // Async validation test('username', 'Username is already taken', async () => { if (data.username) { await enforce(await doesUsernameExist(data.username)).isFalsy(); } }); test('email', 'Email is required', () => { enforce(data.email).isNotBlank(); }); test('email', 'Email must be valid', () => { enforce(data.email).isEmail(); }); test('password', 'Password is required', () => { enforce(data.password).isNotBlank(); }); test('password', 'Password must be at least 8 characters long', () => { enforce(data.password).longerThanOrEquals(8); }); // Conditional validation: only run if password is valid and present if (data.password && signupSuite.get().hasErrors('password') === false) { test('confirmPassword', 'Passwords do not match', () => { enforce(data.confirmPassword).equals(data.password); }); } }); async function validateForm(formData: FormData) { console.log('Validating with data:', formData); const result = await signupSuite.run(formData); console.log('Validation Results:'); console.log(' isValid:', result.isValid()); console.log(' hasErrors:', result.hasErrors()); console.log(' getErrors:', result.getErrors()); console.log(' getWarnings:', result.getWarnings()); if (!result.isValid()) { console.log('Validation failed!'); } else { console.log('Validation passed!'); } } // Example usage validateForm({ username: '', email: 'test@example.com', password: 'password123', confirmPassword: 'password123' }); validateForm({ username: 'john', email: 'john@example.com', password: 'short', confirmPassword: 'short' }); validateForm({ username: 'admin', email: 'admin@example.com', password: 'password123', confirmPassword: 'password123' }); validateForm({ username: 'newUser', email: 'new@example.com', password: 'supersecurepassword', confirmPassword: 'supersecurepassword' });
Debug
Known issues
breakingIn Vest v6, `create` now returns a `Suite Object` with methods like `.run()`, `.reset()`, and `.get()`, instead of directly returning a callable function. Direct calls to the suite function (e.g., `suite(data)`) will result in a TypeError.
fix
Refactor `const result = suite(data);` to `const result = suite.run(data);`. Similarly, `suite.reset()` and `suite.get()` are now methods of the suite object.
affects: >=6.0.0
breakingThe `promisify` utility and the `.done()` callback on the result object were removed in Vest v6. The `suite.run()` method now returns a Promise-like object, simplifying asynchronous handling.
fix
Replace `promisify(suite)` and `suite(data).done(callback)` with `await suite.run(data)` for async operations.
affects: >=6.0.0
breakingThe `test.memo` API was promoted to a top-level `memo` export in Vest v6 and must be imported from `vest/memo`. It now wraps a block of logic, not just individual tests.
fix
Change `import { test } from 'vest'; test.memo(...)` to `import { test } from 'vest'; import { memo } from 'vest/memo'; memo(() => { test(...) }, [dependencies]);`.
affects: >=6.0.0
breakingVest v4 removed default import support (e.g., `import vest from 'vest'`) for better tree-shaking. All core Vest utilities like `create`, `test`, and `enforce` must be explicitly named imports.
fix
Always use named imports: `import { create, test, enforce } from 'vest';`.
affects: >=4.0.0
gotchaUsing standard `if/else` statements to conditionally run tests within a Vest suite can lead to unpredictable behavior and out-of-sync test results, as Vest relies on the consistent order of execution for test state management.
fix
Use Vest's `skipWhen` utility for conditional test execution to maintain correct state tracking: `skipWhen(condition, () => { test(...) });`.
affects: >=4.0.0
gotchaIn Vest v6, focusing or skipping specific fields or groups (e.g., `only`, `skip`) is handled by methods on the `Suite Object` (e.g., `suite.only('fieldName').run(data)`) rather than by passing arguments to `only()` or `skip()` inside the suite callback.
fix
Refactor internal `only(fieldName)` calls within the suite definition to external `suite.only('fieldName').run(formData)` or `suite.focus({ only: 'fieldName' }).run(formData)`.
affects: >=6.0.0
Errors
Common errors & fixes
TypeError: suite is not a function
Attempting to call the result of `create` directly as a function, which was the behavior in Vest v5, but `create` returns a Suite Object in v6.
fix
Call the `.run()` method on the suite object: `const result = mySuite.run(data);`.
ReferenceError: test is not defined
`test` was not correctly imported as a named export. This often happens if attempting a default import (e.g., `import vest from 'vest'`) or if `test` is simply missing from the named import.
fix
Ensure `test` is imported as a named export: `import { create, test, enforce } from 'vest';`.
Cannot read properties of undefined (reading 'isNotBlank')
The `enforce` assertion was called with an `undefined` value, usually when `data.fieldName` is missing or `null` in the input, and Vest attempts to apply an assertion that expects a defined value.
fix
Ensure the field exists or add conditional checks before enforcing: `if (data.username) { enforce(data.username).isNotBlank(); }` or handle `undefined` within your schema definition.
Asynchronous validation is not waiting for completion or result is premature.
Forgetting to `await` the result of `suite.run()` when the suite contains asynchronous tests, or not handling the Promise-like nature of the v6 `SuiteResult` object.
fix
Always `await` the result when working with async validations: `const result = await mySuite.run(data);`.
Upgrade
Version history
0.0.15latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
14 hits · last 30 days
node
12
OpenAI (training)
1
Resources