Valibot
This skill helps you work effectively with
Valibot
, the modular and type-safe schema library for validating structural data.
When to use this skill
When the user asks about schema validation with Valibot
When creating or modifying Valibot schemas
When parsing or validating user input
When the user mentions Valibot, schema, or validation
When migrating from Zod to Valibot
CRITICAL: Valibot vs Zod — Do Not Confuse!
Valibot and Zod have different APIs. Never mix them up!
Key Differences
Feature
Zod ❌
Valibot ✅
Import
import { z } from 'zod'
import * as v from 'valibot'
Validations
Chained methods:
.email().min(5)
Pipeline:
v.pipe(v.string(), v.email(), v.minLength(5))
Parsing
schema.parse(data)
v.parse(schema, data)
Safe parsing
schema.safeParse(data)
v.safeParse(schema, data)
Optional
z.string().optional()
v.optional(v.string())
Nullable
z.string().nullable()
v.nullable(v.string())
Default
z.string().default('x')
v.optional(v.string(), 'x')
Transform
z.string().transform(fn)
v.pipe(v.string(), v.transform(fn))
Refine/Check
z.string().refine(fn)
v.pipe(v.string(), v.check(fn))
Enum
z.enum(['a', 'b'])
v.picklist(['a', 'b'])
Native enum
z.nativeEnum(MyEnum)
v.enum(MyEnum)
Union
z.union([a, b])
v.union([a, b])
Discriminated union
z.discriminatedUnion('type', [...])
v.variant('type', [...])
Intersection
z.intersection(a, b)
v.intersect([a, b])
Min/max length
.min(5).max(10)
v.minLength(5), v.maxLength(10)
Min/max value
.gte(5).lte(10)
v.minValue(5), v.maxValue(10)
Infer type
z.infer
npm
yarn add valibot
yarn
pnpm add valibot
pnpm
bun add valibot
bun
- Import with a wildcard (recommended):
- import
- *
- as
- v
- from
- "valibot"
- ;
- Or with individual imports:
- import
- {
- object
- ,
- string
- ,
- pipe
- ,
- ,
- parse
- }
- from
- "valibot"
- ;
- Mental Model
- Valibot's API is divided into three main concepts:
- 1. Schemas
- Schemas define the expected data type. They are the starting point.
- import
- *
- as
- v
- from
- "valibot"
- ;
- // Primitive schemas
- const
- StringSchema
- =
- v
- .
- string
- (
- )
- ;
- const
- NumberSchema
- =
- v
- .
- number
- (
- )
- ;
- const
- BooleanSchema
- =
- v
- .
- boolean
- (
- )
- ;
- const
- DateSchema
- =
- v
- .
- date
- (
- )
- ;
- // Complex schemas
- const
- ArraySchema
- =
- v
- .
- array
- (
- v
- .
- string
- (
- )
- )
- ;
- const
- ObjectSchema
- =
- v
- .
- object
- (
- {
- name
- :
- v
- .
- string
- (
- )
- ,
- age
- :
- v
- .
- number
- (
- )
- ,
- }
- )
- ;
- 2. Methods
- Methods help you use or modify schemas. The schema is always the first argument.
- // Parsing
- const
- result
- =
- v
- .
- parse
- (
- StringSchema
- ,
- "hello"
- )
- ;
- const
- safeResult
- =
- v
- .
- safeParse
- (
- StringSchema
- ,
- "hello"
- )
- ;
- // Type guard
- if
- (
- v
- .
- is
- (
- StringSchema
- ,
- data
- )
- )
- {
- // data is typed as string
- }
- 3. Actions
- Actions validate or transform data within a
- pipe()
- . They MUST be used inside pipelines.
- // Actions are used in pipe()
- const
- EmailSchema
- =
- v
- .
- pipe
- (
- v
- .
- string
- (
- )
- ,
- v
- .
- trim
- (
- )
- ,
- v
- .
- (
- )
- ,
- v
- .
- endsWith
- (
- "@example.com"
- )
- ,
- )
- ;
- Pipelines
- Pipelines extend schemas with validation and transformation actions. A pipeline always starts with a schema, followed by actions.
- import
- *
- as
- v
- from
- "valibot"
- ;
- const
- UsernameSchema
- =
- v
- .
- pipe
- (
- v
- .
- string
- (
- )
- ,
- v
- .
- trim
- (
- )
- ,
- v
- .
- minLength
- (
- 3
- ,
- "Username must be at least 3 characters"
- )
- ,
- v
- .
- maxLength
- (
- 20
- ,
- "Username must be at most 20 characters"
- )
- ,
- v
- .
- regex
- (
- /
- ^
- [
- a
- -
- z
- 0
- -
- 9
- _
- ]
- +
- $
- /
- i
- ,
- "Username can only contain letters, numbers, and underscores"
- ,
- )
- ,
- )
- ;
- const
- AgeSchema
- =
- v
- .
- pipe
- (
- v
- .
- number
- (
- )
- ,
- v
- .
- integer
- (
- "Age must be a whole number"
- )
- ,
- v
- .
- minValue
- (
- 0
- ,
- "Age cannot be negative"
- )
- ,
- v
- .
- maxValue
- (
- 150
- ,
- "Age cannot exceed 150"
- )
- ,
- )
- ;
- Common Validation Actions
- String validations:
- v.email()
- — Valid email format
- v.url()
- — Valid URL format
- v.uuid()
- — Valid UUID format
- v.regex(pattern)
- — Match regex pattern
- v.minLength(n)
- — Minimum length
- v.maxLength(n)
- — Maximum length
- v.length(n)
- — Exact length
- v.nonEmpty()
- — Not empty string
- v.startsWith(str)
- — Starts with string
- v.endsWith(str)
- — Ends with string
- v.includes(str)
- — Contains string
- Number validations:
- v.minValue(n)
- — Minimum value (>=)
- v.maxValue(n)
- — Maximum value (<=)
- v.gtValue(n)
- — Greater than (>)
- v.ltValue(n)
- — Less than (<)
- v.integer()
- — Must be integer
- v.finite()
- — Must be finite
- v.safeInteger()
- — Safe integer range
- v.multipleOf(n)
- — Must be multiple of n
- Array validations:
- v.minLength(n)
- — Minimum items
- v.maxLength(n)
- — Maximum items
- v.length(n)
- — Exact item count
- v.nonEmpty()
- — At least one item
- v.includes(item)
- — Contains item
- v.excludes(item)
- — Does not contain item
- Custom Validation with check()
- const
- PasswordSchema
- =
- v
- .
- pipe
- (
- v
- .
- string
- (
- )
- ,
- v
- .
- minLength
- (
- 8
- )
- ,
- v
- .
- check
- (
- (
- input
- )
- =>
- /
- [
- A
- -
- Z
- ]
- /
- .
- test
- (
- input
- )
- ,
- "Password must contain an uppercase letter"
- ,
- )
- ,
- v
- .
- check
- (
- (
- input
- )
- =>
- /
- [
- 0
- -
- 9
- ]
- /
- .
- test
- (
- input
- )
- ,
- "Password must contain a number"
- )
- ,
- )
- ;
- Value Transformations
- These actions modify the value without changing its type:
- String transformations:
- v.trim()
- — Remove leading/trailing whitespace
- v.trimStart()
- — Remove leading whitespace
- v.trimEnd()
- — Remove trailing whitespace
- v.toLowerCase()
- — Convert to lowercase
- v.toUpperCase()
- — Convert to uppercase
- Number transformations:
- v.toMinValue(n)
- — Clamp to minimum value (if less than n, set to n)
- v.toMaxValue(n)
- — Clamp to maximum value (if greater than n, set to n)
- const
- NormalizedEmailSchema
- =
- v
- .
- pipe
- (
- v
- .
- string
- (
- )
- ,
- v
- .
- trim
- (
- )
- ,
- v
- .
- toLowerCase
- (
- )
- ,
- v
- .
- (
- )
- ,
- )
- ;
- // Clamp number to range 0-100
- const
- PercentageSchema
- =
- v
- .
- pipe
- (
- v
- .
- number
- (
- )
- ,
- v
- .
- toMinValue
- (
- 0
- )
- ,
- v
- .
- toMaxValue
- (
- 100
- )
- )
- ;
- Type Transformations
- For converting between data types, use these built-in transformation actions:
- v.toNumber()
- — Convert to number
- v.toString()
- — Convert to string
- v.toBoolean()
- — Convert to boolean
- v.toBigint()
- — Convert to bigint
- v.toDate()
- — Convert to Date
- // Convert string to number
- const
- PortSchema
- =
- v
- .
- pipe
- (
- v
- .
- string
- (
- )
- ,
- v
- .
- toNumber
- (
- )
- ,
- v
- .
- integer
- (
- )
- ,
- v
- .
- minValue
- (
- 1
- )
- )
- ;
- // Convert ISO string to Date
- const
- TimestampSchema
- =
- v
- .
- pipe
- (
- v
- .
- string
- (
- )
- ,
- v
- .
- isoDateTime
- (
- )
- ,
- v
- .
- toDate
- (
- )
- )
- ;
- // Convert to boolean
- const
- FlagSchema
- =
- v
- .
- pipe
- (
- v
- .
- string
- (
- )
- ,
- v
- .
- toBoolean
- (
- )
- )
- ;
- Custom Transformations
- For custom transformations, use
- v.transform()
- :
- const
- DateStringSchema
- =
- v
- .
- pipe
- (
- v
- .
- string
- (
- )
- ,
- v
- .
- isoDate
- (
- )
- ,
- v
- .
- transform
- (
- (
- input
- )
- =>
- new
- Date
- (
- input
- )
- )
- ,
- )
- ;
- // Custom object transformation
- const
- UserSchema
- =
- v
- .
- pipe
- (
- v
- .
- object
- (
- {
- firstName
- :
- v
- .
- string
- (
- )
- ,
- lastName
- :
- v
- .
- string
- (
- )
- ,
- }
- )
- ,
- v
- .
- transform
- (
- (
- input
- )
- =>
- (
- {
- ...
- input
- ,
- fullName
- :
- `
- ${
- input
- .
- firstName
- }
- ${
- input
- .
- lastName
- }
- `
- ,
- }
- )
- )
- ,
- )
- ;
- Object Schemas
- Basic Object
- const
- UserSchema
- =
- v
- .
- object
- (
- {
- id
- :
- v
- .
- number
- (
- )
- ,
- name
- :
- v
- .
- string
- (
- )
- ,
- :
- v
- .
- pipe
- (
- v
- .
- string
- (
- )
- ,
- v
- .
- (
- )
- )
- ,
- age
- :
- v
- .
- optional
- (
- v
- .
- number
- (
- )
- )
- ,
- }
- )
- ;
- type
- User
- =
- v
- .
- InferOutput
- <
- typeof
- UserSchema
- >
- ;
- Object Variants
- // Regular object - strips unknown keys (default)
- const
- ObjectSchema
- =
- v
- .
- object
- (
- {
- key
- :
- v
- .
- string
- (
- )
- }
- )
- ;
- // Loose object - allows and preserves unknown keys
- const
- LooseObjectSchema
- =
- v
- .
- looseObject
- (
- {
- key
- :
- v
- .
- string
- (
- )
- }
- )
- ;
- // Strict object - throws on unknown keys
- const
- StrictObjectSchema
- =
- v
- .
- strictObject
- (
- {
- key
- :
- v
- .
- string
- (
- )
- }
- )
- ;
- // Object with rest - validates unknown keys against a schema
- const
- ObjectWithRestSchema
- =
- v
- .
- objectWithRest
- (
- {
- key
- :
- v
- .
- string
- (
- )
- }
- ,
- v
- .
- number
- (
- )
- ,
- // unknown keys must be numbers
- )
- ;
- Optional and Nullable Fields
- const
- ProfileSchema
- =
- v
- .
- object
- (
- {
- // Required
- name
- :
- v
- .
- string
- (
- )
- ,
- // Optional (can be undefined or missing)
- nickname
- :
- v
- .
- optional
- (
- v
- .
- string
- (
- )
- )
- ,
- // Optional with default
- role
- :
- v
- .
- optional
- (
- v
- .
- string
- (
- )
- ,
- "user"
- )
- ,
- // Nullable (can be null)
- avatar
- :
- v
- .
- nullable
- (
- v
- .
- string
- (
- )
- )
- ,
- // Nullish (can be null or undefined)
- bio
- :
- v
- .
- nullish
- (
- v
- .
- string
- (
- )
- )
- ,
- // Nullish with default
- theme
- :
- v
- .
- nullish
- (
- v
- .
- string
- (
- )
- ,
- "light"
- )
- ,
- }
- )
- ;
- Object Methods
- const
- BaseSchema
- =
- v
- .
- object
- (
- {
- id
- :
- v
- .
- number
- (
- )
- ,
- name
- :
- v
- .
- string
- (
- )
- ,
- :
- v
- .
- string
- (
- )
- ,
- password
- :
- v
- .
- string
- (
- )
- ,
- }
- )
- ;
- // Pick specific keys
- const
- PublicUserSchema
- =
- v
- .
- pick
- (
- BaseSchema
- ,
- [
- "id"
- ,
- "name"
- ]
- )
- ;
- // Omit specific keys
- const
- UserWithoutPasswordSchema
- =
- v
- .
- omit
- (
- BaseSchema
- ,
- [
- "password"
- ]
- )
- ;
- // Make all optional
- const
- PartialUserSchema
- =
- v
- .
- partial
- (
- BaseSchema
- )
- ;
- // Make all required
- const
- RequiredUserSchema
- =
- v
- .
- required
- (
- PartialUserSchema
- )
- ;
- // Merge objects
- const
- ExtendedUserSchema
- =
- v
- .
- object
- (
- {
- ...
- BaseSchema
- .
- entries
- ,
- createdAt
- :
- v
- .
- date
- (
- )
- ,
- }
- )
- ;
- Cross-Field Validation
- const
- RegistrationSchema
- =
- v
- .
- pipe
- (
- v
- .
- object
- (
- {
- password
- :
- v
- .
- pipe
- (
- v
- .
- string
- (
- )
- ,
- v
- .
- minLength
- (
- 8
- )
- )
- ,
- confirmPassword
- :
- v
- .
- string
- (
- )
- ,
- }
- )
- ,
- v
- .
- forward
- (
- v
- .
- partialCheck
- (
- [
- [
- "password"
- ]
- ,
- [
- "confirmPassword"
- ]
- ]
- ,
- (
- input
- )
- =>
- input
- .
- password
- ===
- input
- .
- confirmPassword
- ,
- "Passwords do not match"
- ,
- )
- ,
- [
- "confirmPassword"
- ]
- ,
- )
- ,
- )
- ;
- Arrays and Tuples
- Arrays
- const
- TagsSchema
- =
- v
- .
- pipe
- (
- v
- .
- array
- (
- v
- .
- string
- (
- )
- )
- ,
- v
- .
- minLength
- (
- 1
- ,
- "At least one tag required"
- )
- ,
- v
- .
- maxLength
- (
- 10
- ,
- "Maximum 10 tags allowed"
- )
- ,
- )
- ;
- // Array of objects
- const
- UsersSchema
- =
- v
- .
- array
- (
- v
- .
- object
- (
- {
- id
- :
- v
- .
- number
- (
- )
- ,
- name
- :
- v
- .
- string
- (
- )
- ,
- }
- )
- ,
- )
- ;
- Tuples
- // Fixed-length array with specific types
- const
- CoordinatesSchema
- =
- v
- .
- tuple
- (
- [
- v
- .
- number
- (
- )
- ,
- v
- .
- number
- (
- )
- ]
- )
- ;
- // Type: [number, number]
- // Tuple with rest
- const
- ArgsSchema
- =
- v
- .
- tupleWithRest
- (
- [
- v
- .
- string
- (
- )
- ]
- ,
- // first arg is string
- v
- .
- number
- (
- )
- ,
- // rest are numbers
- )
- ;
- // Type: [string, ...number[]]
- Unions and Variants
- Union
- const
- StringOrNumberSchema
- =
- v
- .
- union
- (
- [
- v
- .
- string
- (
- )
- ,
- v
- .
- number
- (
- )
- ]
- )
- ;
- const
- StatusSchema
- =
- v
- .
- union
- (
- [
- v
- .
- literal
- (
- "pending"
- )
- ,
- v
- .
- literal
- (
- "active"
- )
- ,
- v
- .
- literal
- (
- "inactive"
- )
- ,
- ]
- )
- ;
- Picklist (for string/number literals)
- // Simpler than union of literals
- const
- StatusSchema
- =
- v
- .
- picklist
- (
- [
- "pending"
- ,
- "active"
- ,
- "inactive"
- ]
- )
- ;
- const
- PrioritySchema
- =
- v
- .
- picklist
- (
- [
- 1
- ,
- 2
- ,
- 3
- ]
- )
- ;
- Variant (discriminated union)
- Use
- variant
- for better performance with discriminated unions:
- const
- EventSchema
- =
- v
- .
- variant
- (
- "type"
- ,
- [
- v
- .
- object
- (
- {
- type
- :
- v
- .
- literal
- (
- "click"
- )
- ,
- x
- :
- v
- .
- number
- (
- )
- ,
- y
- :
- v
- .
- number
- (
- )
- ,
- }
- )
- ,
- v
- .
- object
- (
- {
- type
- :
- v
- .
- literal
- (
- "keypress"
- )
- ,
- key
- :
- v
- .
- string
- (
- )
- ,
- }
- )
- ,
- v
- .
- object
- (
- {
- type
- :
- v
- .
- literal
- (
- "scroll"
- )
- ,
- direction
- :
- v
- .
- picklist
- (
- [
- "up"
- ,
- "down"
- ]
- )
- ,
- }
- )
- ,
- ]
- )
- ;
- Parsing Data
- parse() — Throws on Error
- import
- *
- as
- v
- from
- "valibot"
- ;
- const
- EmailSchema
- =
- v
- .
- pipe
- (
- v
- .
- string
- (
- )
- ,
- v
- .
- (
- )
- )
- ;
- try
- {
- const
- =
- v
- .
- parse
- (
- EmailSchema
- ,
- "jane@example.com"
- )
- ;
- console
- .
- log
- (
- )
- ;
- // 'jane@example.com'
- }
- catch
- (
- error
- )
- {
- console
- .
- error
- (
- error
- )
- ;
- // ValiError
- }
- safeParse() — Returns Result Object
- const
- result
- =
- v
- .
- safeParse
- (
- EmailSchema
- ,
- input
- )
- ;
- if
- (
- result
- .
- success
- )
- {
- console
- .
- log
- (
- result
- .
- output
- )
- ;
- // Valid data
- }
- else
- {
- console
- .
- log
- (
- result
- .
- issues
- )
- ;
- // Array of issues
- }
- is() — Type Guard
- if
- (
- v
- .
- is
- (
- EmailSchema
- ,
- input
- )
- )
- {
- // input is typed as string
- }
- Configuration Options
- // Abort early - stop at first error
- v
- .
- parse
- (
- Schema
- ,
- data
- ,
- {
- abortEarly
- :
- true
- }
- )
- ;
- // Abort pipe early - stop pipeline at first error
- v
- .
- parse
- (
- Schema
- ,
- data
- ,
- {
- abortPipeEarly
- :
- true
- }
- )
- ;
- Type Inference
- import
- *
- as
- v
- from
- "valibot"
- ;
- const
- UserSchema
- =
- v
- .
- object
- (
- {
- name
- :
- v
- .
- string
- (
- )
- ,
- age
- :
- v
- .
- pipe
- (
- v
- .
- string
- (
- )
- ,
- v
- .
- transform
- (
- Number
- )
- )
- ,
- role
- :
- v
- .
- optional
- (
- v
- .
- string
- (
- )
- ,
- "user"
- )
- ,
- }
- )
- ;
- // Output type (after transformations and defaults)
- type
- User
- =
- v
- .
- InferOutput
- <
- typeof
- UserSchema
- >
- ;
- //
- // Input type (before transformations)
- type
- UserInput
- =
- v
- .
- InferInput
- <
- typeof
- UserSchema
- >
- ;
- //
- // Issue type
- type
- UserIssue
- =
- v
- .
- InferIssue
- <
- typeof
- UserSchema
- >
- ;
- Error Handling
- Custom Error Messages
- const
- LoginSchema
- =
- v
- .
- object
- (
- {
- :
- v
- .
- pipe
- (
- v
- .
- string
- (
- "Email must be a string"
- )
- ,
- v
- .
- nonEmpty
- (
- "Please enter your email"
- )
- ,
- v
- .
- (
- "Invalid email format"
- )
- ,
- )
- ,
- password
- :
- v
- .
- pipe
- (
- v
- .
- string
- (
- "Password must be a string"
- )
- ,
- v
- .
- nonEmpty
- (
- "Please enter your password"
- )
- ,
- v
- .
- minLength
- (
- 8
- ,
- "Password must be at least 8 characters"
- )
- ,
- )
- ,
- }
- )
- ;
- Flattening Errors
- const
- result
- =
- v
- .
- safeParse
- (
- LoginSchema
- ,
- data
- )
- ;
- if
- (
- !
- result
- .
- success
- )
- {
- const
- flat
- =
- v
- .
- flatten
- (
- result
- .
- issues
- )
- ;
- // { nested: { email: ['Invalid email format'], password: ['...'] } }
- }
- Issue Structure
- Each issue contains:
- kind
-
- 'schema' | 'validation' | 'transformation'
- type
-
- Function name (e.g., 'string', 'email', 'min_length')
- input
-
- The problematic input
- expected
-
- What was expected
- received
-
- What was received
- message
-
- Human-readable message
- path
- Array of path items for nested issues
Fallback Values
// Static fallback
const
NumberSchema
=
v
.
fallback
(
v
.
number
(
)
,
0
)
;
v
.
parse
(
NumberSchema
,
"invalid"
)
;
// Returns 0
// Dynamic fallback
const
DateSchema
=
v
.
fallback
(
v
.
date
(
)
,
(
)
=>
new
Date
(
)
)
;
Recursive Schemas
import
*
as
v
from
"valibot"
;
type
TreeNode
=
{
value
:
string
;
children
:
TreeNode
[
]
;
}
;
const
TreeNodeSchema
:
v
.
GenericSchema
<
TreeNode
= v . object ( { value : v . string ( ) , children : v . lazy ( ( ) => v . array ( TreeNodeSchema ) ) , } ) ; Async Validation For async operations (e.g., database checks), use async variants: import * as v from "valibot" ; const isUsernameAvailable = async ( username : string ) => { // Check database return true ; } ; const UsernameSchema = v . pipeAsync ( v . string ( ) , v . minLength ( 3 ) , v . checkAsync ( isUsernameAvailable , "Username is already taken" ) , ) ; // Must use parseAsync const username = await v . parseAsync ( UsernameSchema , "john" ) ; JSON Schema Conversion import { toJsonSchema } from "@valibot/to-json-schema" ; import * as v from "valibot" ; const EmailSchema = v . pipe ( v . string ( ) , v . email ( ) ) ; const jsonSchema = toJsonSchema ( EmailSchema ) ; // { type: 'string', format: 'email' } Naming Conventions Convention 1: Same Name (Recommended for simplicity) export const User = v . object ( { name : v . string ( ) , email : v . pipe ( v . string ( ) , v . email ( ) ) , } ) ; export type User = v . InferOutput < typeof User
; // Usage const users : User [ ] = [ ] ; users . push ( v . parse ( User , data ) ) ; Convention 2: With Suffixes (Recommended when input/output differ) export const UserSchema = v . object ( { name : v . string ( ) , age : v . pipe ( v . string ( ) , v . transform ( Number ) ) , } ) ; export type UserInput = v . InferInput < typeof UserSchema
; export type UserOutput = v . InferOutput < typeof UserSchema
; Common Patterns Login Form const LoginSchema = v . object ( { email : v . pipe ( v . string ( ) , v . nonEmpty ( "Please enter your email" ) , v . email ( "Invalid email address" ) , ) , password : v . pipe ( v . string ( ) , v . nonEmpty ( "Please enter your password" ) , v . minLength ( 8 , "Password must be at least 8 characters" ) , ) , } ) ; API Response const ApiResponseSchema = v . variant ( "status" , [ v . object ( { status : v . literal ( "success" ) , data : v . unknown ( ) , } ) , v . object ( { status : v . literal ( "error" ) , error : v . object ( { code : v . string ( ) , message : v . string ( ) , } ) , } ) , ] ) ; Environment Variables const EnvSchema = v . object ( { NODE_ENV : v . picklist ( [ "development" , "production" , "test" ] ) , PORT : v . pipe ( v . string ( ) , v . transform ( Number ) , v . integer ( ) , v . minValue ( 1 ) ) , DATABASE_URL : v . pipe ( v . string ( ) , v . url ( ) ) , API_KEY : v . pipe ( v . string ( ) , v . minLength ( 32 ) ) , } ) ; const env = v . parse ( EnvSchema , process . env ) ; Date Handling // String to Date const DateFromStringSchema = v . pipe ( v . string ( ) , v . isoDate ( ) , v . transform ( ( input ) => new Date ( input ) ) , ) ; // Date validation const FutureDateSchema = v . pipe ( v . date ( ) , v . minValue ( new Date ( ) , "Date must be in the future" ) , ) ; Additional Resources Valibot Documentation Valibot GitHub API Reference Migration from Zod