Gathering detailed insights and metrics for @hookform/resolvers
Gathering detailed insights and metrics for @hookform/resolvers
Gathering detailed insights and metrics for @hookform/resolvers
Gathering detailed insights and metrics for @hookform/resolvers
@dudeofawesome/hookform-resolvers
React Hook Form validation resolvers: Yup, Joi, Superstruct, Zod, Vest, Class Validator, io-ts, Nope, computed-types, TypeBox, arktype, Typanion, Effect-TS and VineJS
@psymorias/hookform-resolvers-ajv
React Hook Form validation resolvers: Yup, Joi, Superstruct, Ajv and etc.
@jorgebarredo/resolvers
React Hook Form validation resolvers: Yup, Joi, Superstruct, Zod, Vest, Class Validator, io-ts, Nope, computed-types and Typanion
@nish1896/rhf-mui-components
A suite of 20+ reusable Material UI components for React Hook Form to minimize your time and effort in creating and styling forms
📋 Validation resolvers: Yup, Zod, Superstruct, Joi, Vest, Class Validator, io-ts, Nope, computed-types, typanion, Ajv, TypeBox, ArkType, Valibot, effect-ts, VineJS and Standard Schema
npm install @hookform/resolvers
Typescript
Module System
Node Version
NPM Version
97.7
Supply Chain
89.4
Quality
94
Maintenance
100
Vulnerability
100
License
TypeScript (98.44%)
Shell (1.23%)
JavaScript (0.33%)
Verify real, reachable, and deliverable emails with instant MX records, SMTP checks, and disposable email detection.
Total Downloads
315,826,207
Last Day
957,762
Last Week
4,968,707
Last Month
20,491,770
Last Year
166,500,210
MIT License
1,924 Stars
355 Commits
176 Forks
12 Watchers
5 Branches
63 Contributors
Updated on Mar 13, 2025
Minified
Minified + Gzipped
Latest Version
4.1.3
Package Id
@hookform/resolvers@4.1.3
Unpacked Size
848.38 kB
Size
105.27 kB
File Count
397
NPM Version
10.9.2
Node Version
20.18.3
Published on
Mar 03, 2025
Cumulative downloads
Total Downloads
Last Day
9.3%
957,762
Compared to previous day
Last Week
6.2%
4,968,707
Compared to previous week
Last Month
18.5%
20,491,770
Compared to previous month
Last Year
90.5%
166,500,210
Compared to previous year
1
1
48
Performant, flexible and extensible forms with easy to use validation.
This function allows you to use any external validation library such as Yup, Zod, Joi, Vest, Ajv and many others. The goal is to make sure you can seamlessly integrate whichever validation library you prefer. If you're not using a library, you can always write your own logic to validate your forms.
Install your preferred validation library alongside @hookform/resolvers
.
npm install @hookform/resolvers # npm
yarn add @hookform/resolvers # yarn
pnpm install @hookform/resolvers # pnpm
bun install @hookform/resolvers # bun
resolver | Infer values from schema | criteriaMode |
---|---|---|
AJV | ❌ | `firstError |
Arktype | ✅ | firstError |
class-validator | ✅ | `firstError |
computed-types | ✅ | firstError |
Effect | ✅ | `firstError |
fluentvalidation-ts | ❌ | firstError |
io-ts | ✅ | firstError |
joi | ❌ | `firstError |
Nope | ❌ | firstError |
Standard Schema | ✅ | `firstError |
Superstruct | ✅ | firstError |
typanion | ✅ | firstError |
typebox | ✅ | `firstError |
typeschema | ❌ | `firstError |
valibot | ✅ | `firstError |
vest | ❌ | `firstError |
vine | ✅ | `firstError |
yup | ✅ | `firstError |
zod | ✅ | `firstError |
type Options = {
mode: 'async' | 'sync',
raw?: boolean
}
resolver(schema: object, schemaOptions?: object, resolverOptions: Options)
type | Required | Description | |
---|---|---|---|
schema | object | ✓ | validation schema |
schemaOptions | object | validation library schema options | |
resolverOptions | object | resolver options, async is the default mode |
Dead simple Object schema validation.
1import { useForm } from 'react-hook-form'; 2import { yupResolver } from '@hookform/resolvers/yup'; 3import * as yup from 'yup'; 4 5const schema = yup 6 .object() 7 .shape({ 8 name: yup.string().required(), 9 age: yup.number().required(), 10 }) 11 .required(); 12 13const App = () => { 14 const { register, handleSubmit } = useForm({ 15 resolver: yupResolver(schema), 16 }); 17 18 return ( 19 <form onSubmit={handleSubmit((d) => console.log(d))}> 20 <input {...register('name')} /> 21 <input type="number" {...register('age')} /> 22 <input type="submit" /> 23 </form> 24 ); 25};
TypeScript-first schema validation with static type inference
⚠️ Example below uses the
valueAsNumber
, which requiresreact-hook-form
v6.12.0 (released Nov 28, 2020) or later.
1import { useForm } from 'react-hook-form'; 2import { zodResolver } from '@hookform/resolvers/zod'; 3import { z } from 'zod'; 4 5const schema = z.object({ 6 name: z.string().min(1, { message: 'Required' }), 7 age: z.number().min(10), 8}); 9 10const App = () => { 11 const { 12 register, 13 handleSubmit, 14 formState: { errors }, 15 } = useForm({ 16 resolver: zodResolver(schema), 17 }); 18 19 return ( 20 <form onSubmit={handleSubmit((d) => console.log(d))}> 21 <input {...register('name')} /> 22 {errors.name?.message && <p>{errors.name?.message}</p>} 23 <input type="number" {...register('age', { valueAsNumber: true })} /> 24 {errors.age?.message && <p>{errors.age?.message}</p>} 25 <input type="submit" /> 26 </form> 27 ); 28};
A simple and composable way to validate data in JavaScript (or TypeScript).
1import { useForm } from 'react-hook-form'; 2import { superstructResolver } from '@hookform/resolvers/superstruct'; 3import { object, string, number } from 'superstruct'; 4 5const schema = object({ 6 name: string(), 7 age: number(), 8}); 9 10const App = () => { 11 const { register, handleSubmit } = useForm({ 12 resolver: superstructResolver(schema), 13 }); 14 15 return ( 16 <form onSubmit={handleSubmit((d) => console.log(d))}> 17 <input {...register('name')} /> 18 <input type="number" {...register('age', { valueAsNumber: true })} /> 19 <input type="submit" /> 20 </form> 21 ); 22};
The most powerful data validation library for JS.
1import { useForm } from 'react-hook-form'; 2import { joiResolver } from '@hookform/resolvers/joi'; 3import Joi from 'joi'; 4 5const schema = Joi.object({ 6 name: Joi.string().required(), 7 age: Joi.number().required(), 8}); 9 10const App = () => { 11 const { register, handleSubmit } = useForm({ 12 resolver: joiResolver(schema), 13 }); 14 15 return ( 16 <form onSubmit={handleSubmit((d) => console.log(d))}> 17 <input {...register('name')} /> 18 <input type="number" {...register('age')} /> 19 <input type="submit" /> 20 </form> 21 ); 22};
Vest 🦺 Declarative Validation Testing.
1import { useForm } from 'react-hook-form'; 2import { vestResolver } from '@hookform/resolvers/vest'; 3import { create, test, enforce } from 'vest'; 4 5const validationSuite = create((data = {}) => { 6 test('username', 'Username is required', () => { 7 enforce(data.username).isNotEmpty(); 8 }); 9 10 test('password', 'Password is required', () => { 11 enforce(data.password).isNotEmpty(); 12 }); 13}); 14 15const App = () => { 16 const { register, handleSubmit, errors } = useForm({ 17 resolver: vestResolver(validationSuite), 18 }); 19 20 return ( 21 <form onSubmit={handleSubmit((data) => console.log(data))}> 22 <input {...register('username')} /> 23 <input type="password" {...register('password')} /> 24 <input type="submit" /> 25 </form> 26 ); 27};
Decorator-based property validation for classes.
⚠️ Remember to add these options to your
tsconfig.json
!
"strictPropertyInitialization": false,
"experimentalDecorators": true
1import { useForm } from 'react-hook-form'; 2import { classValidatorResolver } from '@hookform/resolvers/class-validator'; 3import { Length, Min, IsEmail } from 'class-validator'; 4 5class User { 6 @Length(2, 30) 7 username: string; 8 9 @IsEmail() 10 email: string; 11} 12 13const resolver = classValidatorResolver(User); 14 15const App = () => { 16 const { 17 register, 18 handleSubmit, 19 formState: { errors }, 20 } = useForm<User>({ resolver }); 21 22 return ( 23 <form onSubmit={handleSubmit((data) => console.log(data))}> 24 <input type="text" {...register('username')} /> 25 {errors.username && <span>{errors.username.message}</span>} 26 <input type="text" {...register('email')} /> 27 {errors.email && <span>{errors.email.message}</span>} 28 <input type="submit" value="Submit" /> 29 </form> 30 ); 31};
Validate your data with powerful decoders.
1import React from 'react'; 2import { useForm } from 'react-hook-form'; 3import { ioTsResolver } from '@hookform/resolvers/io-ts'; 4import t from 'io-ts'; 5// you don't have to use io-ts-types, but it's very useful 6import tt from 'io-ts-types'; 7 8const schema = t.type({ 9 username: t.string, 10 age: tt.NumberFromString, 11}); 12 13const App = () => { 14 const { register, handleSubmit } = useForm({ 15 resolver: ioTsResolver(schema), 16 }); 17 18 return ( 19 <form onSubmit={handleSubmit((d) => console.log(d))}> 20 <input {...register('username')} /> 21 <input type="number" {...register('age')} /> 22 <input type="submit" /> 23 </form> 24 ); 25}; 26 27export default App;
A small, simple, and fast JS validator
1import { useForm } from 'react-hook-form'; 2import { nopeResolver } from '@hookform/resolvers/nope'; 3import Nope from 'nope-validator'; 4 5const schema = Nope.object().shape({ 6 name: Nope.string().required(), 7 age: Nope.number().required(), 8}); 9 10const App = () => { 11 const { register, handleSubmit } = useForm({ 12 resolver: nopeResolver(schema), 13 }); 14 15 return ( 16 <form onSubmit={handleSubmit((d) => console.log(d))}> 17 <input {...register('name')} /> 18 <input type="number" {...register('age')} /> 19 <input type="submit" /> 20 </form> 21 ); 22};
TypeScript-first schema validation with static type inference
1import { useForm } from 'react-hook-form'; 2import { computedTypesResolver } from '@hookform/resolvers/computed-types'; 3import Schema, { number, string } from 'computed-types'; 4 5const schema = Schema({ 6 username: string.min(1).error('username field is required'), 7 age: number, 8}); 9 10const App = () => { 11 const { 12 register, 13 handleSubmit, 14 formState: { errors }, 15 } = useForm({ 16 resolver: computedTypesResolver(schema), 17 }); 18 19 return ( 20 <form onSubmit={handleSubmit((d) => console.log(d))}> 21 <input {...register('name')} /> 22 {errors.name?.message && <p>{errors.name?.message}</p>} 23 <input type="number" {...register('age', { valueAsNumber: true })} /> 24 {errors.age?.message && <p>{errors.age?.message}</p>} 25 <input type="submit" /> 26 </form> 27 ); 28};
Static and runtime type assertion library with no dependencies
1import { useForm } from 'react-hook-form'; 2import { typanionResolver } from '@hookform/resolvers/typanion'; 3import * as t from 'typanion'; 4 5const isUser = t.isObject({ 6 username: t.applyCascade(t.isString(), [t.hasMinLength(1)]), 7 age: t.applyCascade(t.isNumber(), [ 8 t.isInteger(), 9 t.isInInclusiveRange(1, 100), 10 ]), 11}); 12 13const App = () => { 14 const { 15 register, 16 handleSubmit, 17 formState: { errors }, 18 } = useForm({ 19 resolver: typanionResolver(isUser), 20 }); 21 22 return ( 23 <form onSubmit={handleSubmit((d) => console.log(d))}> 24 <input {...register('name')} /> 25 {errors.name?.message && <p>{errors.name?.message}</p>} 26 <input type="number" {...register('age')} /> 27 {errors.age?.message && <p>{errors.age?.message}</p>} 28 <input type="submit" /> 29 </form> 30 ); 31};
The fastest JSON validator for Node.js and browser
1import { useForm } from 'react-hook-form'; 2import { ajvResolver } from '@hookform/resolvers/ajv'; 3 4// must use `minLength: 1` to implement required field 5const schema = { 6 type: 'object', 7 properties: { 8 username: { 9 type: 'string', 10 minLength: 1, 11 errorMessage: { minLength: 'username field is required' }, 12 }, 13 password: { 14 type: 'string', 15 minLength: 1, 16 errorMessage: { minLength: 'password field is required' }, 17 }, 18 }, 19 required: ['username', 'password'], 20 additionalProperties: false, 21}; 22 23const App = () => { 24 const { 25 register, 26 handleSubmit, 27 formState: { errors }, 28 } = useForm({ 29 resolver: ajvResolver(schema), 30 }); 31 32 return ( 33 <form onSubmit={handleSubmit((data) => console.log(data))}> 34 <input {...register('username')} /> 35 {errors.username && <span>{errors.username.message}</span>} 36 <input {...register('password')} /> 37 {errors.password && <span>{errors.password.message}</span>} 38 <button type="submit">submit</button> 39 </form> 40 ); 41};
JSON Schema Type Builder with Static Type Resolution for TypeScript
ValueCheck
1import { useForm } from 'react-hook-form'; 2import { typeboxResolver } from '@hookform/resolvers/typebox'; 3import { Type } from '@sinclair/typebox'; 4 5const schema = Type.Object({ 6 username: Type.String({ minLength: 1 }), 7 password: Type.String({ minLength: 1 }), 8}); 9 10const App = () => { 11 const { register, handleSubmit } = useForm({ 12 resolver: typeboxResolver(schema), 13 }); 14 15 return ( 16 <form onSubmit={handleSubmit((d) => console.log(d))}> 17 <input {...register('username')} /> 18 <input type="password" {...register('password')} /> 19 <input type="submit" /> 20 </form> 21 ); 22};
TypeCompiler
A high-performance JIT of TypeBox
, read more
1import { useForm } from 'react-hook-form'; 2import { typeboxResolver } from '@hookform/resolvers/typebox'; 3import { Type } from '@sinclair/typebox'; 4import { TypeCompiler } from '@sinclair/typebox/compiler'; 5 6const schema = Type.Object({ 7 username: Type.String({ minLength: 1 }), 8 password: Type.String({ minLength: 1 }), 9}); 10 11const typecheck = TypeCompiler.Compile(schema); 12 13const App = () => { 14 const { register, handleSubmit } = useForm({ 15 resolver: typeboxResolver(typecheck), 16 }); 17 18 return ( 19 <form onSubmit={handleSubmit((d) => console.log(d))}> 20 <input {...register('username')} /> 21 <input type="password" {...register('password')} /> 22 <input type="submit" /> 23 </form> 24 ); 25};
TypeScript's 1:1 validator, optimized from editor to runtime
1import { useForm } from 'react-hook-form'; 2import { arktypeResolver } from '@hookform/resolvers/arktype'; 3import { type } from 'arktype'; 4 5const schema = type({ 6 username: 'string>1', 7 password: 'string>1', 8}); 9 10const App = () => { 11 const { register, handleSubmit } = useForm({ 12 resolver: arktypeResolver(schema), 13 }); 14 15 return ( 16 <form onSubmit={handleSubmit((d) => console.log(d))}> 17 <input {...register('username')} /> 18 <input type="password" {...register('password')} /> 19 <input type="submit" /> 20 </form> 21 ); 22};
The modular and type safe schema library for validating structural data
1import { useForm } from 'react-hook-form'; 2import { valibotResolver } from '@hookform/resolvers/valibot'; 3import * as v from 'valibot'; 4 5const schema = v.object({ 6 username: v.pipe( 7 v.string('username is required'), 8 v.minLength(3, 'Needs to be at least 3 characters'), 9 v.endsWith('cool', 'Needs to end with `cool`'), 10 ), 11 password: v.string('password is required'), 12}); 13 14const App = () => { 15 const { register, handleSubmit } = useForm({ 16 resolver: valibotResolver(schema), 17 }); 18 19 return ( 20 <form onSubmit={handleSubmit((d) => console.log(d))}> 21 <input {...register('username')} /> 22 <input type="password" {...register('password')} /> 23 <input type="submit" /> 24 </form> 25 ); 26};
Universal adapter for schema validation, compatible with any validation library
1import { useForm } from 'react-hook-form'; 2import { typeschemaResolver } from '@hookform/resolvers/typeschema'; 3import { z } from 'zod'; 4 5// Use your favorite validation library 6const schema = z.object({ 7 username: z.string().min(1, { message: 'Required' }), 8 password: z.number().min(1, { message: 'Required' }), 9}); 10 11const App = () => { 12 const { register, handleSubmit } = useForm({ 13 resolver: typeschemaResolver(schema), 14 }); 15 16 return ( 17 <form onSubmit={handleSubmit((d) => console.log(d))}> 18 <input {...register('username')} /> 19 <input type="password" {...register('password')} /> 20 <input type="submit" /> 21 </form> 22 ); 23};
A powerful TypeScript framework that provides a fully-fledged functional effect system with a rich standard library.
1import React from 'react'; 2import { useForm } from 'react-hook-form'; 3import { effectTsResolver } from '@hookform/resolvers/effect-ts'; 4import { Schema } from 'effect'; 5 6const schema = Schema.Struct({ 7 username: Schema.String.pipe( 8 Schema.nonEmptyString({ message: () => 'username required' }), 9 ), 10 password: Schema.String.pipe( 11 Schema.nonEmptyString({ message: () => 'password required' }), 12 ), 13}); 14 15type FormData = typeof schema.Type; 16 17interface Props { 18 onSubmit: (data: FormData) => void; 19} 20 21function TestComponent({ onSubmit }: Props) { 22 const { 23 register, 24 handleSubmit, 25 formState: { errors }, 26 // provide generic if TS has issues inferring types 27 } = useForm<FormData>({ 28 resolver: effectTsResolver(schema), 29 }); 30 31 return ( 32 <form onSubmit={handleSubmit(onSubmit)}> 33 <input {...register('username')} /> 34 {errors.username && <span role="alert">{errors.username.message}</span>} 35 36 <input {...register('password')} /> 37 {errors.password && <span role="alert">{errors.password.message}</span>} 38 39 <button type="submit">submit</button> 40 </form> 41 ); 42}
VineJS is a form data validation library for Node.js
1import { useForm } from 'react-hook-form'; 2import { vineResolver } from '@hookform/resolvers/vine'; 3import vine from '@vinejs/vine'; 4 5const schema = vine.compile( 6 vine.object({ 7 username: vine.string().minLength(1), 8 password: vine.string().minLength(1), 9 }), 10); 11 12const App = () => { 13 const { register, handleSubmit } = useForm({ 14 resolver: vineResolver(schema), 15 }); 16 17 return ( 18 <form onSubmit={handleSubmit((d) => console.log(d))}> 19 <input {...register('username')} /> 20 {errors.username && <span role="alert">{errors.username.message}</span>} 21 <input {...register('password')} /> 22 {errors.password && <span role="alert">{errors.password.message}</span>} 23 <button type="submit">submit</button> 24 </form> 25 ); 26};
A TypeScript-first library for building strongly-typed validation rules
1import { useForm } from 'react-hook-form'; 2import { fluentValidationResolver } from '@hookform/resolvers/fluentvalidation-ts'; 3import { Validator } from 'fluentvalidation-ts'; 4 5class FormDataValidator extends Validator<FormData> { 6 constructor() { 7 super(); 8 9 this.ruleFor('username') 10 .notEmpty() 11 .withMessage('username is a required field'); 12 this.ruleFor('password') 13 .notEmpty() 14 .withMessage('password is a required field'); 15 } 16} 17 18const App = () => { 19 const { register, handleSubmit } = useForm({ 20 resolver: fluentValidationResolver(new FormDataValidator()), 21 }); 22 23 return ( 24 <form onSubmit={handleSubmit((d) => console.log(d))}> 25 <input {...register('username')} /> 26 {errors.username && <span role="alert">{errors.username.message}</span>} 27 <input {...register('password')} /> 28 {errors.password && <span role="alert">{errors.password.message}</span>} 29 <button type="submit">submit</button> 30 </form> 31 ); 32};
A standard interface for TypeScript schema validation libraries
Example zod
1import { useForm } from 'react-hook-form'; 2import { standardSchemaResolver } from '@hookform/resolvers/standard-schema'; 3import { z } from 'zod'; 4 5const schema = z.object({ 6 name: z.string().min(1, { message: 'Required' }), 7 age: z.number().min(10), 8}); 9 10const App = () => { 11 const { 12 register, 13 handleSubmit, 14 formState: { errors }, 15 } = useForm({ 16 resolver: standardSchemaResolver(schema), 17 }); 18 19 return ( 20 <form onSubmit={handleSubmit((d) => console.log(d))}> 21 <input {...register('name')} /> 22 {errors.name?.message && <p>{errors.name?.message}</p>} 23 <input type="number" {...register('age', { valueAsNumber: true })} /> 24 {errors.age?.message && <p>{errors.age?.message}</p>} 25 <input type="submit" /> 26 </form> 27 ); 28};
Example arkType
1import { useForm } from 'react-hook-form'; 2import { standardSchemaResolver } from '@hookform/resolvers/standard-schema'; 3import { type } from 'arktype'; 4 5const schema = type({ 6 username: 'string>1', 7 password: 'string>1', 8}); 9 10const App = () => { 11 const { register, handleSubmit } = useForm({ 12 resolver: standardSchemaResolver(schema), 13 }); 14 15 return ( 16 <form onSubmit={handleSubmit((d) => console.log(d))}> 17 <input {...register('username')} /> 18 <input type="password" {...register('password')} /> 19 <input type="submit" /> 20 </form> 21 ); 22};
Thanks go to all our backers! [Become a backer].
Thanks go to these wonderful people! [Become a contributor].
No vulnerabilities found.
Reason
15 commit(s) and 15 issue activity found in the last 90 days -- score normalized to 10
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
Reason
Found 27/30 approved changesets -- score normalized to 9
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2025-03-03
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More