Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/react-hook-form/resolvers

📋 Validation resolvers: Yup, Zod, AJV, Joi, Superstruct, Vest, class-validator, io-ts, typanion, Ajv, TypeBox, Valibot and nope.
https://github.com/react-hook-form/resolvers

ajv class-validator computed-types form form-validation hacktoberfest hooks io-ts joi jsonschema resolvers schema-validation superstruct typebox typescript validation yup zod

Last synced: 26 days ago
JSON representation

📋 Validation resolvers: Yup, Zod, AJV, Joi, Superstruct, Vest, class-validator, io-ts, typanion, Ajv, TypeBox, Valibot and nope.

Awesome Lists containing this project

README

        




React Hook Form Logo - React hook custom hook for form validation


Performant, flexible and extensible forms with easy to use validation.

[![npm downloads](https://img.shields.io/npm/dm/@hookform/resolvers.svg?style=for-the-badge)](https://www.npmjs.com/package/@hookform/resolvers)
[![npm](https://img.shields.io/npm/dt/@hookform/resolvers.svg?style=for-the-badge)](https://www.npmjs.com/package/@hookform/resolvers)
[![npm](https://img.shields.io/bundlephobia/minzip/@hookform/resolvers?style=for-the-badge)](https://bundlephobia.com/result?p=@hookform/resolvers)

## Install

npm install @hookform/resolvers

## Links

- [React-hook-form validation resolver documentation ](https://react-hook-form.com/api/useform/#resolver)

### Supported resolvers

- [Install](#install)
- [Links](#links)
- [Supported resolvers](#supported-resolvers)
- [API](#api)
- [Quickstart](#quickstart)
- [Yup](#yup)
- [Zod](#zod)
- [Superstruct](#superstruct)
- [Joi](#joi)
- [Vest](#vest)
- [Class Validator](#class-validator)
- [io-ts](#io-ts)
- [Nope](#nope)
- [computed-types](#computed-types)
- [typanion](#typanion)
- [Ajv](#ajv)
- [TypeBox](#typebox)
- [With `ValueCheck`](#with-valuecheck)
- [With `TypeCompiler`](#with-typecompiler)
- [ArkType](#arktype)
- [Valibot](#valibot)
- [TypeSchema](#typeschema)
- [effect-ts](#effect-ts)
- [VineJS](#vinejs)
- [fluentvalidation-ts](#fluentvalidation-ts)
- [Backers](#backers)
- [Sponsors](#sponsors)
- [Contributors](#contributors)

## API

```
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 |

## Quickstart

### [Yup](https://github.com/jquense/yup)

Dead simple Object schema validation.

[![npm](https://img.shields.io/bundlephobia/minzip/yup?style=for-the-badge)](https://bundlephobia.com/result?p=yup)

```typescript jsx
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';

const schema = yup
.object()
.shape({
name: yup.string().required(),
age: yup.number().required(),
})
.required();

const App = () => {
const { register, handleSubmit } = useForm({
resolver: yupResolver(schema),
});

return (
console.log(d))}>




);
};
```

### [Zod](https://github.com/vriad/zod)

TypeScript-first schema validation with static type inference

[![npm](https://img.shields.io/bundlephobia/minzip/zod?style=for-the-badge)](https://bundlephobia.com/result?p=zod)

> ⚠️ Example below uses the `valueAsNumber`, which requires `react-hook-form` v6.12.0 (released Nov 28, 2020) or later.

```tsx
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';

const schema = z.object({
name: z.string().min(1, { message: 'Required' }),
age: z.number().min(10),
});

const App = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: zodResolver(schema),
});

return (
console.log(d))}>

{errors.name?.message &&

{errors.name?.message}

}

{errors.age?.message &&

{errors.age?.message}

}


);
};
```

### [Superstruct](https://github.com/ianstormtaylor/superstruct)

A simple and composable way to validate data in JavaScript (or TypeScript).

[![npm](https://img.shields.io/bundlephobia/minzip/superstruct?style=for-the-badge)](https://bundlephobia.com/result?p=superstruct)

```typescript jsx
import { useForm } from 'react-hook-form';
import { superstructResolver } from '@hookform/resolvers/superstruct';
import { object, string, number } from 'superstruct';

const schema = object({
name: string(),
age: number(),
});

const App = () => {
const { register, handleSubmit } = useForm({
resolver: superstructResolver(schema),
});

return (
console.log(d))}>




);
};
```

### [Joi](https://github.com/sideway/joi)

The most powerful data validation library for JS.

[![npm](https://img.shields.io/bundlephobia/minzip/joi?style=for-the-badge)](https://bundlephobia.com/result?p=joi)

```typescript jsx
import { useForm } from 'react-hook-form';
import { joiResolver } from '@hookform/resolvers/joi';
import Joi from 'joi';

const schema = Joi.object({
name: Joi.string().required(),
age: Joi.number().required(),
});

const App = () => {
const { register, handleSubmit } = useForm({
resolver: joiResolver(schema),
});

return (
console.log(d))}>




);
};
```

### [Vest](https://github.com/ealush/vest)

Vest 🦺 Declarative Validation Testing.

[![npm](https://img.shields.io/bundlephobia/minzip/vest?style=for-the-badge)](https://bundlephobia.com/result?p=vest)

```typescript jsx
import { useForm } from 'react-hook-form';
import { vestResolver } from '@hookform/resolvers/vest';
import { create, test, enforce } from 'vest';

const validationSuite = create((data = {}) => {
test('username', 'Username is required', () => {
enforce(data.username).isNotEmpty();
});

test('password', 'Password is required', () => {
enforce(data.password).isNotEmpty();
});
});

const App = () => {
const { register, handleSubmit, errors } = useForm({
resolver: vestResolver(validationSuite),
});

return (
console.log(data))}>




);
};
```

### [Class Validator](https://github.com/typestack/class-validator)

Decorator-based property validation for classes.

[![npm](https://img.shields.io/bundlephobia/minzip/class-validator?style=for-the-badge)](https://bundlephobia.com/result?p=class-validator)

> ⚠️ Remember to add these options to your `tsconfig.json`!

```
"strictPropertyInitialization": false,
"experimentalDecorators": true
```

```tsx
import { useForm } from 'react-hook-form';
import { classValidatorResolver } from '@hookform/resolvers/class-validator';
import { Length, Min, IsEmail } from 'class-validator';

class User {
@Length(2, 30)
username: string;

@IsEmail()
email: string;
}

const resolver = classValidatorResolver(User);

const App = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({ resolver });

return (
console.log(data))}>

{errors.username && {errors.username.message}}

{errors.email && {errors.email.message}}


);
};
```

### [io-ts](https://github.com/gcanti/io-ts)

Validate your data with powerful decoders.

[![npm](https://img.shields.io/bundlephobia/minzip/io-ts?style=for-the-badge)](https://bundlephobia.com/result?p=io-ts)

```typescript jsx
import React from 'react';
import { useForm } from 'react-hook-form';
import { ioTsResolver } from '@hookform/resolvers/io-ts';
import t from 'io-ts';
// you don't have to use io-ts-types, but it's very useful
import tt from 'io-ts-types';

const schema = t.type({
username: t.string,
age: tt.NumberFromString,
});

const App = () => {
const { register, handleSubmit } = useForm({
resolver: ioTsResolver(schema),
});

return (
console.log(d))}>




);
};

export default App;
```

### [Nope](https://github.com/bvego/nope-validator)

A small, simple, and fast JS validator

[![npm](https://img.shields.io/bundlephobia/minzip/nope-validator?style=for-the-badge)](https://bundlephobia.com/result?p=nope-validator)

```typescript jsx
import { useForm } from 'react-hook-form';
import { nopeResolver } from '@hookform/resolvers/nope';
import Nope from 'nope-validator';

const schema = Nope.object().shape({
name: Nope.string().required(),
age: Nope.number().required(),
});

const App = () => {
const { register, handleSubmit } = useForm({
resolver: nopeResolver(schema),
});

return (
console.log(d))}>




);
};
```

### [computed-types](https://github.com/neuledge/computed-types)

TypeScript-first schema validation with static type inference

[![npm](https://img.shields.io/bundlephobia/minzip/computed-types?style=for-the-badge)](https://bundlephobia.com/result?p=computed-types)

```tsx
import { useForm } from 'react-hook-form';
import { computedTypesResolver } from '@hookform/resolvers/computed-types';
import Schema, { number, string } from 'computed-types';

const schema = Schema({
username: string.min(1).error('username field is required'),
age: number,
});

const App = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: computedTypesResolver(schema),
});

return (
console.log(d))}>

{errors.name?.message &&

{errors.name?.message}

}

{errors.age?.message &&

{errors.age?.message}

}


);
};
```

### [typanion](https://github.com/arcanis/typanion)

Static and runtime type assertion library with no dependencies

[![npm](https://img.shields.io/bundlephobia/minzip/typanion?style=for-the-badge)](https://bundlephobia.com/result?p=typanion)

```tsx
import { useForm } from 'react-hook-form';
import { typanionResolver } from '@hookform/resolvers/typanion';
import * as t from 'typanion';

const isUser = t.isObject({
username: t.applyCascade(t.isString(), [t.hasMinLength(1)]),
age: t.applyCascade(t.isNumber(), [
t.isInteger(),
t.isInInclusiveRange(1, 100),
]),
});

const App = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: typanionResolver(isUser),
});

return (
console.log(d))}>

{errors.name?.message &&

{errors.name?.message}

}

{errors.age?.message &&

{errors.age?.message}

}


);
};
```

### [Ajv](https://github.com/ajv-validator/ajv)

The fastest JSON validator for Node.js and browser

[![npm](https://img.shields.io/bundlephobia/minzip/ajv?style=for-the-badge)](https://bundlephobia.com/result?p=ajv)

```tsx
import { useForm } from 'react-hook-form';
import { ajvResolver } from '@hookform/resolvers/ajv';

// must use `minLength: 1` to implement required field
const schema = {
type: 'object',
properties: {
username: {
type: 'string',
minLength: 1,
errorMessage: { minLength: 'username field is required' },
},
password: {
type: 'string',
minLength: 1,
errorMessage: { minLength: 'password field is required' },
},
},
required: ['username', 'password'],
additionalProperties: false,
};

const App = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: ajvResolver(schema),
});

return (
console.log(data))}>

{errors.username && {errors.username.message}}

{errors.password && {errors.password.message}}
submit

);
};
```

### [TypeBox](https://github.com/sinclairzx81/typebox)

JSON Schema Type Builder with Static Type Resolution for TypeScript

[![npm](https://img.shields.io/bundlephobia/minzip/@sinclair/typebox?style=for-the-badge)](https://bundlephobia.com/result?p=@sinclair/typebox)

#### With `ValueCheck`

```typescript jsx
import { useForm } from 'react-hook-form';
import { typeboxResolver } from '@hookform/resolvers/typebox';
import { Type } from '@sinclair/typebox';

const schema = Type.Object({
username: Type.String({ minLength: 1 }),
password: Type.String({ minLength: 1 }),
});

const App = () => {
const { register, handleSubmit } = useForm({
resolver: typeboxResolver(schema),
});

return (
console.log(d))}>




);
};
```

#### With `TypeCompiler`

A high-performance JIT of `TypeBox`, [read more](https://github.com/sinclairzx81/typebox#typecompiler)

```typescript jsx
import { useForm } from 'react-hook-form';
import { typeboxResolver } from '@hookform/resolvers/typebox';
import { Type } from '@sinclair/typebox';
import { TypeCompiler } from '@sinclair/typebox/compiler';

const schema = Type.Object({
username: Type.String({ minLength: 1 }),
password: Type.String({ minLength: 1 }),
});

const typecheck = TypeCompiler.Compile(schema);

const App = () => {
const { register, handleSubmit } = useForm({
resolver: typeboxResolver(typecheck),
});

return (
console.log(d))}>




);
};
```

### [ArkType](https://github.com/arktypeio/arktype)

TypeScript's 1:1 validator, optimized from editor to runtime

[![npm](https://img.shields.io/bundlephobia/minzip/arktype?style=for-the-badge)](https://bundlephobia.com/result?p=arktype)

```typescript jsx
import { useForm } from 'react-hook-form';
import { arktypeResolver } from '@hookform/resolvers/arktype';
import { type } from 'arktype';

const schema = type({
username: 'string>1',
password: 'string>1',
});

const App = () => {
const { register, handleSubmit } = useForm({
resolver: arktypeResolver(schema),
});

return (
console.log(d))}>




);
};
```

### [Valibot](https://github.com/fabian-hiller/valibot)

The modular and type safe schema library for validating structural data

[![npm](https://img.shields.io/bundlephobia/minzip/valibot?style=for-the-badge)](https://bundlephobia.com/result?p=valibot)

```typescript jsx
import { useForm } from 'react-hook-form';
import { valibotResolver } from '@hookform/resolvers/valibot';
import * as v from 'valibot';

const schema = v.object({
username: v.pipe(
v.string('username is required'),
v.minLength(3, 'Needs to be at least 3 characters'),
v.endsWith('cool', 'Needs to end with `cool`'),
),
password: v.string('password is required'),
});

const App = () => {
const { register, handleSubmit } = useForm({
resolver: valibotResolver(schema),
});

return (
console.log(d))}>




);
};
```

### [TypeSchema](https://typeschema.com)

Universal adapter for schema validation, compatible with [any validation library](https://typeschema.com/#coverage)

[![npm](https://img.shields.io/bundlephobia/minzip/@typeschema/main?style=for-the-badge)](https://bundlephobia.com/result?p=@typeschema/main)

```typescript jsx
import { useForm } from 'react-hook-form';
import { typeschemaResolver } from '@hookform/resolvers/typeschema';
import * as z from 'zod';

// Use your favorite validation library
const schema = z.object({
username: z.string().min(1, { message: 'Required' }),
password: z.number().min(1, { message: 'Required' }),
});

const App = () => {
const { register, handleSubmit } = useForm({
resolver: typeschemaResolver(schema),
});

return (
console.log(d))}>




);
};
```

### [effect-ts](https://github.com/Effect-TS/effect)

A powerful TypeScript framework that provides a fully-fledged functional effect system with a rich standard library.

[![npm](https://img.shields.io/bundlephobia/minzip/@effect/schema?style=for-the-badge)](https://bundlephobia.com/result?p=effect)

```typescript jsx
import React from 'react';
import { useForm } from 'react-hook-form';
import { effectTsResolver } from '@hookform/resolvers/effect-ts';
import { Schema } from '@effect/schema';

const schema = Schema.Struct({
username: Schema.String.pipe(
Schema.nonEmpty({ message: () => 'username required' }),
),
password: Schema.String.pipe(
Schema.nonEmpty({ message: () => 'password required' }),
),
});

type FormData = Schema.Schema.Type;

interface Props {
onSubmit: (data: FormData) => void;
}

function TestComponent({ onSubmit }: Props) {
const {
register,
handleSubmit,
formState: { errors },
// provide generic if TS has issues inferring types
} = useForm({
resolver: effectTsResolver(schema),
});

return (


{errors.username && {errors.username.message}}


{errors.password && {errors.password.message}}

submit

);
}
```

### [VineJS](https://github.com/vinejs/vine)

VineJS is a form data validation library for Node.js

[![npm](https://img.shields.io/bundlephobia/minzip/@vinejs/vine?style=for-the-badge)](https://bundlephobia.com/result?p=@vinejs/vine)

```typescript jsx
import { useForm } from 'react-hook-form';
import { vineResolver } from '@hookform/resolvers/vine';
import vine from '@vinejs/vine';

const schema = vine.compile(
vine.object({
username: vine.string().minLength(1),
password: vine.string().minLength(1),
}),
);

const App = () => {
const { register, handleSubmit } = useForm({
resolver: vineResolver(schema),
});

return (
console.log(d))}>

{errors.username && {errors.username.message}}

{errors.password && {errors.password.message}}
submit

);
};
```

### [fluentvalidation-ts](https://github.com/AlexJPotter/fluentvalidation-ts)

A TypeScript-first library for building strongly-typed validation rules

[![npm](https://img.shields.io/bundlephobia/minzip/@vinejs/vine?style=for-the-badge)](https://bundlephobia.com/result?p=@vinejs/vine)

```typescript jsx
import { useForm } from 'react-hook-form';
import { fluentValidationResolver } from '@hookform/resolvers/fluentvalidation-ts';
import { Validator } from 'fluentvalidation-ts';

class FormDataValidator extends Validator {
constructor() {
super();

this.ruleFor('username')
.notEmpty()
.withMessage('username is a required field');
this.ruleFor('password')
.notEmpty()
.withMessage('password is a required field');
}
}

const App = () => {
const { register, handleSubmit } = useForm({
resolver: fluentValidationResolver(new FormDataValidator()),
});

return (
console.log(d))}>

{errors.username && {errors.username.message}}

{errors.password && {errors.password.message}}
submit

);
};
```

## Backers

Thanks go to all our backers! [[Become a backer](https://opencollective.com/react-hook-form#backer)].



## Contributors

Thanks go to these wonderful people! [[Become a contributor](CONTRIBUTING.md)].