Quick start

My schema can be compared to a type definition in TypeScript. The big difference is that TypeScript types are "not executed" and are more or less a DX feature. A schema on the other hand, apart from the inferred type definition, can also be executed at runtime to guarantee type safety of unknown data.

Until I reach v1, I welcome lots of feedback on the API, naming and implementation. Please create or reply to an issue and help me become the best schema library for JavaScript and TypeScript.

Basic concept

Similar to how types can be defined in TypeScript, my source code allows you to define a schema with various small functions. This applies to primitive values like strings as well as to more complex data sets like objects.

import * as v from 'valibot';

// TypeScript
type LoginData = {
  email: string;
  password: string;

// Valibot
const LoginSchema = v.object({
  email: v.string(),
  password: v.string(),


In addition, I can help you to perform more detailed validations and transformations with the pipe method. Thus, for example, it can be ensured that a string is an email and ends with a certain domain.

import * as v from 'valibot';

const EmailSchema = v.pipe(v.string(), v.email(), v.endsWith('@example.com'));

A pipeline must always start with a schema, followed by up to 19 validation or transformation actions. They are executed in sequence, and the result of the previous action is passed to the next. More details about pipelines can be found in this guide.

Error messages

If I detect an issue during validation, I create a specific issue object with various details and an error message. This error message can be overridden via the first optional argument of a schema or validation action.

import * as v from 'valibot';

const LoginSchema = v.object({
  email: v.pipe(
    v.string('Your email must be a string.'),
    v.nonEmpty('Please enter your email.'),
    v.email('The email address is badly formatted.')
  password: v.pipe(
    v.string('Your password must be a string.'),
    v.nonEmpty('Please enter your password.'),
    v.minLength(8, 'Your password must have 8 characters or more.')

Custom error messages allow you to improve the usability of your software by providing specific troubleshooting information and returning error messages in a language other than English. See the i18n guide for more information.


Finally, you can use your schema to infer its input and output types and to parse unknown data. This way, your schema is the single source of truth. This concept simplifies your development process and makes your code more robust in the long run.

import * as v from 'valibot';

const LoginSchema = v.object({});

type LoginData = v.InferOutput<typeof LoginSchema>;

function getLoginData(data: unknown): LoginData {
  return v.parse(LoginSchema, data);


Thanks to all the contributors who helped make this page better!

  • GitHub profile picture of fabian-hiller


Thanks to our partners who support the project ideally and financially.


Thanks to our GitHub sponsors who support the project financially.

  • GitHub profile picture of dailydotdev
  • GitHub profile picture of Thanaen
  • GitHub profile picture of KATT
  • GitHub profile picture of osdiab
  • GitHub profile picture of ruiaraujo012
  • GitHub profile picture of hyunbinseo
  • GitHub profile picture of F0rce
  • GitHub profile picture of caegdeveloper
  • GitHub profile picture of seahindeniz