Gathering detailed insights and metrics for conform-to-valibot
Gathering detailed insights and metrics for conform-to-valibot
Gathering detailed insights and metrics for conform-to-valibot
Gathering detailed insights and metrics for conform-to-valibot
npm install conform-to-valibot
Typescript
Module System
Node Version
NPM Version
79.8
Supply Chain
99.5
Quality
83.1
Maintenance
100
Vulnerability
100
License
TypeScript (99.88%)
JavaScript (0.12%)
Total Downloads
130,680
Last Day
196
Last Week
2,478
Last Month
17,631
Last Year
125,609
MIT License
56 Stars
68 Commits
8 Forks
1 Watchers
4 Branches
7 Contributors
Updated on May 29, 2025
Minified
Minified + Gzipped
Latest Version
1.15.2
Package Id
conform-to-valibot@1.15.2
Unpacked Size
50.69 kB
Size
8.23 kB
File Count
7
NPM Version
10.9.2
Node Version
20.19.0
Published on
Apr 27, 2025
Cumulative downloads
Total Downloads
Last Day
-3.4%
196
Compared to previous day
Last Week
-33.7%
2,478
Compared to previous week
Last Month
-27.2%
17,631
Compared to previous month
Last Year
2,377%
125,609
Compared to previous year
2
[!WARNING]
The official valibot support library based on this library has been released. This project will be archived in the near future. To migrate, just install the official library(npm install @conform-to/valibot
) and change the reference.
1- import { parseWithValibot } from 'conform-to-valibot'; 2+ import { parseWithValibot } from '@conform-to/valibot';
Conform helpers for integrating with Valibot
1npm install @conform-to/react valibot conform-to-valibot
It parses the formData and returns a submission result with the validation error. If no error is found, the parsed data will also be populated as submission.value
.
1import { useForm } from '@conform-to/react'; 2import { parseWithValibot } from 'conform-to-valibot'; 3import { object, string } from 'valibot'; 4 5const schema = object({ 6 email: string('Email is required' ), 7 password: string('Password is required' ), 8}); 9 10function ExampleForm() { 11 const [form, { email, password }] = useForm({ 12 onValidate({ formData }) { 13 return parseWithValibot(formData, { 14 schema, 15 }); 16 }, 17 }); 18 19 // ... 20}
Or when parsing the formData on server side (e.g. Remix):
1import { useForm } from '@conform-to/react'; 2import { parseWithValibot } from 'conform-to-valibot'; 3import { object } from 'valibot'; 4 5const schema = object({ 6 // Define the schema with valibot 7}); 8 9export async function action({ request }) { 10 const formData = await request.formData(); 11 const submission = await parseWithValibot(formData, { 12 schema, 13 }); 14 15 // Send the submission back to the client if the status is not successful 16 if (submission.status !== 'success') { 17 return submission.reply(); 18 } 19 20 // ... 21}
You can skip an validation to use the previous result. On client validation, you can indicate the validation is not defined to fallback to server validation.
1import type { Intent } from "@conform-to/react";
2import { useForm } from '@conform-to/react';
3import { parseWithValibot } from 'conform-to-valibot';
4import {
5 check,
6 forward,
7 forwardAsync,
8 object,
9 partialCheck,
10 partialCheckAsync,
11 pipe,
12 pipeAsync,
13 string,
14} from "valibot";
15
16function createBaseSchema(intent: Intent | null) {
17 return object({
18 email: pipe(
19 string("Email is required"),
20 // When not validating email, leave the email error as it is.
21 check(
22 () =>
23 intent === null ||
24 (intent.type === "validate" && intent.payload.name === "email"),
25 conformValibotMessage.VALIDATION_SKIPPED,
26 ),
27 ),
28 password: string("Password is required"),
29 });
30}
31
32function createServerSchema(
33 intent: Intent | null,
34 options: { isEmailUnique: (email: string) => Promise<boolean> },
35) {
36 return pipeAsync(
37 createBaseSchema(intent),
38 forwardAsync(
39 partialCheckAsync(
40 [["email"]],
41 async ({ email }) => options.isEmailUnique(email),
42 "Email is already used",
43 ),
44 ["email"],
45 ),
46 );
47}
48
49function createClientSchema(intent: Intent | null) {
50 return pipe(
51 createBaseSchema(intent),
52 forward(
53 // If email is specified, fallback to server validation to check its uniqueness.
54 partialCheck(
55 [["email"]],
56 () => false,
57 conformValibotMessage.VALIDATION_UNDEFINED,
58 ),
59 ["email"],
60 ),
61 );
62}
63
64export async function action({ request }) {
65 const formData = await request.formData();
66 const submission = await parseWithValibot(formData, {
67 schema: (intent) =>
68 createServerSchema(intent, {
69 isEmailUnique: async (email) => {
70 // Query your database to check if the email is unique
71 },
72 }),
73 });
74
75 // Send the submission back to the client if the status is not successful
76 if (submission.status !== "success") {
77 return submission.reply();
78 }
79
80 // ...
81}
82
83function ExampleForm() {
84 const [form, { email, password }] = useForm({
85 onValidate({ formData }) {
86 return parseWithValibot(formData, {
87 schema: (intent) => createClientSchema(intent),
88 });
89 },
90 });
91
92 // ...
93}
By default, parseWithValibot
will strip empty value and coerce form data to the correct type by introspecting the schema and inject extra preprocessing steps using the valibotFormValue
helper internally.
If you want to customize this behavior, you can disable automatic type coercion by setting options.disableAutoCoercion
to true
and manage it yourself.
1import { useForm } from '@conform-to/react'; 2import { parseWithValibot, unstable_valibotFormValue as valibotFormValue } from 'conform-to-valibot'; 3import { pipe, transform, unknown, object, string } from 'valibot'; 4 5// `parseWithValibot` implicitly performs the following forced conversion: 6const schema = object({ 7 name: pipe(unknown(), transform(v => v === "" ? undefined ? v), string('Name is required' )), 8 age: pipe(unknown(), transform(v => Number(v)), number('Age is required number' )), 9}); 10 11function ExampleForm() { 12 const [form, { email, password }] = useForm({ 13 onValidate({ formData }) { 14 return parseWithValibot(formData, { 15 schema, 16 disableAutoCoercion: true 17 }); 18 }, 19 }); 20 21 // ... 22}
A helper that returns an object containing the validation attributes for each field by introspecting the valibot schema.
1import { getValibotConstraint } from "conform-to-valibot"; 2import { useForm } from "@conform-to/react"; 3import { object, string, pipe, minLength, maxLength, optional } from "valibot"; 4 5const schema = object({ 6 title: pipe(string(), minLength(10), maxLength(100)), 7 description: optional(pipe(string(), minLength(100), maxLength(1000))), 8}); 9 10function Example() { 11 const [form, fields] = useForm({ 12 constraint: getValibotConstraint(schema), 13 }); 14 15 // ... 16}
A helper that enhances the schema with extra preprocessing steps to strip empty value and coerce form value to the expected type.
1const enhancedSchema = coerceFormValue(schema, options);
The following rules will be applied by default:
undefined
to the schemav.number()
, trim the value and cast it with the Number
constructorv.boolean()
, treat the value as true
if it equals to on
(Browser default value
of a checkbox / radio button)v.date()
, cast the value with the Date
constructorv.bigint()
, trim the value and cast the value with the BigInt
constructor1import { parseWithValibot, unstable_coerceFormValue as coerceFormValue } from '@conform-to/valibot'; 2import { useForm } from '@conform-to/react'; 3import { object, string, date, number, boolean } from 'valibot'; 4import { jsonSchema } from './jsonSchema'; 5 6const metadata = object({ 7 number: number(), 8 confirmed: boolean(), 9}); 10 11const schema = coerceFormValue( 12 object({ 13 ref: string() 14 date: date(), 15 amount: number(), 16 confirm: boolean(), 17 metadata, 18 }), 19 { 20 defaultCoercion: { 21 // Override the default coercion with `number()` 22 number: (value) => { 23 // Pass the value as is if it's not a string 24 if (typeof value !== 'string') { 25 return value; 26 } 27 28 // Trim and remove commas before casting it to number 29 return Number(value.trim().replace(/,/g, '')); 30 }, 31 32 // Disable coercion for `boolean()` 33 boolean: false, 34 }, 35 customize(schema) { 36 // Customize how the `metadata` field value is coerced 37 if (schema === metadata) { 38 return (value) => { 39 if (typeof value !== 'string') { 40 return value; 41 } 42 43 // Parse the value as JSON 44 return JSON.parse(value); 45 }; 46 } 47 48 // Return `null` to keep the default behavior 49 return null; 50 }, 51 }, 52); 53 54function Example() { 55 const [form, fields] = useForm({ 56 onValidate({ formData }) { 57 return parseWithValibot(formData, { 58 schema, 59 defaultTypeCoercion: false, 60 }); 61 }, 62 }); 63 64 // ... 65}
No vulnerabilities found.
No security vulnerabilities found.