Sourcemap Explorer
Stack · npm package

@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

latest 5.7.1· MIT· 148 versions publishedView on npm

About

React Hook Form validation resolvers: Yup, Joi, Superstruct, Zod, Vest, Class Validator, io-ts, Nope, computed-types, TypeBox, arktype, Typanion, Effect-TS and VineJS

schemevalidationscheme-validationhookformreact-hook-formyupjoisuperstructtypescriptzodvestclass-validatorio-tseffect-tsnopecomputed-typestypanionajvTypeBoxarktypetypeschemavinefluentvalidation-tsstandard-schema

What detecting @hookform/resolvers tells you about a site

This package is glue, and that is exactly what makes it informative: it bridges react-hook-form to an external validation schema. Finding it means two things at once are present in the app: react-hook-form as the form engine, and a separate schema library such as zod, yup or joi doing the actual validation. It reveals a deliberately layered form architecture where the form state management and the validation rules are kept as separate concerns. Its presence is a near-certain marker of a modern, performance-minded React form setup that values uncontrolled inputs and schema-driven errors.

Why the exact @hookform/resolvers version matters

The resolvers package tracks the APIs of every validator it adapts, so its version matters indirectly: a given release supports particular major versions of zod, yup and the rest. A mismatch between an old resolvers build and a newer schema library is a real source of subtle validation bugs, so the pinned version hints at which schema-library era the project targets.

@hookform/resolvers in a real-world stack

When you find @hookform/resolvers in a bundle, it rarely travels alone. react-hook-form always, plus exactly one schema library, most often zod or yup.

Quick facts

Latest version5.7.1
LicenseMIT
Authorbluebill1049
Installnpm install @hookform/resolvers
Direct dependencies1
Peer dependenciesajv, joi, yup, zod, vest, fp-ts, io-ts, effect, arktype, valibot, typanion, ajv-errors, ajv-formats, superstruct, @vinejs/vine, ata-validator, computed-types, nope-validator, class-validator, react-hook-form, @typeschema/main, @sinclair/typebox, class-transformer, fluentvalidation-ts, @standard-schema/spec

Common pairings

Packages this one expects to find in the same project. Each is also a Sourcemap Explorer detection target.

ajvjoiyupzodvestfp-tsio-tseffectarktypevalibottypanionajv-errorsajv-formatssuperstruct@vinejs/vineata-validatorcomputed-typesnope-validatorclass-validatorreact-hook-form@typeschema/main@sinclair/typeboxclass-transformerfluentvalidation-ts@standard-schema/spec

What @hookform/resolvers pulls in

@hookform/resolvers declares 1 direct dependency — each one also rides into any bundle that ships @hookform/resolvers, so they are detection targets too. Reading them is a quick way to understand the package's real footprint .

@standard-schema/utils

How Sourcemap Explorer detects @hookform/resolvers

@hookform/resolvers ships as v5.7.1, published 2026-08-02 and carries 1 direct dependency, 25 peer dependencies (ajv, joi, yup), 148 versions on the registry. Those exact numbers are the footprint Sourcemap Explorer matches when @hookform/resolvers rides inside a deployed bundle — here is how the detection works.

We catch @hookform/resolvers from two complementary signals: bundled source paths and the embedded package.json. Modern bundlers (webpack, Vite, esbuild, Rollup, Turbopack) preserve the original node_modules/@hookform/resolvers/ paths inside the JavaScript sourcemap's sources[] array — that's the canonical signal. When the matching package.json is also captured in sourcesContent[], we read the exact version field — patch number included. No regex guessing, no version inference.

  1. 1

    Confirm the site exposes sourcemaps

    In DevTools Network, check the response headers of any application script for `SourceMap` or `X-SourceMap`. Failing that, fetch the script's last 4 KB and look for a `//# sourceMappingURL=` comment — that map is where the `@hookform/resolvers` paths live.

  2. 2

    Find the package in the bundle

    Open DevTools → Network → reload. Click any application script and look at its sourcemap. Inside, search `sources[]` for entries matching `node_modules/@hookform/resolvers/` — every match confirms the package is bundled. The matching `sourcesContent[i]` for `node_modules/@hookform/resolvers/package.json` gives you the exact installed version.

  3. 3

    Read the version directly from package.json

    Run `jq -r '. as $m | $m.sources | to_entries[] | select(.value | endswith("node_modules/@hookform/resolvers/package.json")) | $m.sourcesContent[.key] | fromjson | .version' bundle.js.map`. Sourcemap Explorer automates the same query in the popup.

Major releases of @hookform/resolvers

When each major version first landed. Major bumps are where breaking changes live, so this timeline is the fastest way to date the @hookform/resolvers version a site actually ships against the ecosystem.

Major
First release
Date
v5
5.0.0
2025-04-01
v4
4.0.0
2025-02-10
v3
3.0.0
2023-03-20
v2
2.0.0
2021-04-02
v1
1.0.0
2020-10-03
v0
0.0.1
2020-05-20

Recent versions

Version
Released
5.7.1
2026-08-02
5.7.0
2026-08-02
5.6.0
2026-08-01
5.5.8
2026-08-01
5.5.7
2026-07-26
5.5.6
2026-07-26
5.5.5
2026-07-26
5.5.4
2026-07-26

@hookform/resolvers README

Live mirror of the GitHub README, for reference. Updated whenever the repo's default branch changes.

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

npm downloads npm npm

React Hook Form Resolvers

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

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 Comparison
resolverInfer values
from schema
criteriaMode
AJVfirstError | all
ata-validatorfirstError | all
ArktypefirstError
class-validatorfirstError | all
computed-typesfirstError
EffectfirstError | all
fluentvalidation-tsfirstError
io-tsfirstError
joifirstError | all
NopefirstError
Standard SchemafirstError | all
SuperstructfirstError
typanionfirstError
typeboxfirstError | all
typeschemafirstError | all
valibotfirstError | all
vestfirstError | all
vinefirstError | all
yupfirstError | all
zodfirstError | all

TypeScript

Most of the resolvers can infer the output type from the schema. See comparison table for more details.

useForm<Input, Context, Output>()

Example:

import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod'; // or 'zod/v4'

const schema = z.object({
  id: z.number(),
});

// Automatically infers the output type from the schema
useForm({
  resolver: zodResolver(schema),
});

// Force the output type
useForm<z.input<typeof schema>, any, z.output<typeof schema>>({
  resolver: zodResolver(schema),
});

Links

Table of Contents

API

type Options = {
  mode: 'async' | 'sync',
  raw?: boolean
}

resolver(schema: object, schemaOptions?: object, resolverOptions: Options)
typeRequiredDescription
schemaobjectvalidation schema
schemaOptionsobjectvalidation library schema options
resolverOptionsobjectresolver options, async is the default mode

Quickstart

Yup

Dead simple Object schema validation.

npm

⚠️ Pass context via useForm({ context }), not via yupResolver's schemaOptions. schemaOptions.context is overridden by the form context, so use the useForm context object instead.

// Correct
useForm({
  resolver: yupResolver(schema),
  context: { foo: true },
});

// Avoid - schemaOptions.context will be ignored/overridden
yupResolver(schema, { context: { foo: true } });
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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('name')} />
      <input type="number" {...register('age')} />
      <input type="submit" />
    </form>
  );
};

Zod

TypeScript-first schema validation with static type inference

npm

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

import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod'; // or 'zod/v4'

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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('name')} />
      {errors.name?.message && <p>{errors.name?.message}</p>}
      <input type="number" {...register('age', { valueAsNumber: true })} />
      {errors.age?.message && <p>{errors.age?.message}</p>}
      <input type="submit" />
    </form>
  );
};

⚠️ If your schema uses .default(...) on a field, that field becomes optional on the schema's input type (z.input) but stays required on its output type (z.output/z.infer) — the default only fills it in after validation. Passing a single generic to useForm<T> pins both to the same type and will conflict with zodResolver, which infers input and output separately. Either omit the generic and let it infer from resolver, or specify all three explicitly:

const schema = z.object({ debug_mode: z.boolean().default(true) });

useForm<z.input<typeof schema>, unknown, z.output<typeof schema>>({
  resolver: zodResolver(schema),
});

Superstruct

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

npm

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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('name')} />
      <input type="number" {...register('age', { valueAsNumber: true })} />
      <input type="submit" />
    </form>
  );
};

Joi

The most powerful data validation library for JS.

npm

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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('name')} />
      <input type="number" {...register('age')} />
      <input type="submit" />
    </form>
  );
};

Vest

Vest 🦺 Declarative Validation Testing.

npm

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 } = useForm({
    resolver: vestResolver(validationSuite),
  });

  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <input {...register('username')} />
      <input type="password" {...register('password')} />
      <input type="submit" />
    </form>
  );
};

Class Validator

Decorator-based property validation for classes.

npm

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

"strictPropertyInitialization": false,
"experimentalDecorators": true
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<User>({ resolver });

  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <input type="text" {...register('username')} />
      {errors.username && <span>{errors.username.message}</span>}
      <input type="text" {...register('email')} />
      {errors.email && <span>{errors.email.message}</span>}
      <input type="submit" value="Submit" />
    </form>
  );
};

io-ts

Validate your data with powerful decoders.

npm

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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('username')} />
      <input type="number" {...register('age')} />
      <input type="submit" />
    </form>
  );
};

export default App;

Nope

A small, simple, and fast JS validator

npm

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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('name')} />
      <input type="number" {...register('age')} />
      <input type="submit" />
    </form>
  );
};

computed-types

TypeScript-first schema validation with static type inference

npm

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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('name')} />
      {errors.name?.message && <p>{errors.name?.message}</p>}
      <input type="number" {...register('age', { valueAsNumber: true })} />
      {errors.age?.message && <p>{errors.age?.message}</p>}
      <input type="submit" />
    </form>
  );
};

typanion

Static and runtime type assertion library with no dependencies

npm

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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('name')} />
      {errors.name?.message && <p>{errors.name?.message}</p>}
      <input type="number" {...register('age')} />
      {errors.age?.message && <p>{errors.age?.message}</p>}
      <input type="submit" />
    </form>
  );
};

Ajv

The fastest JSON validator for Node.js and browser

npm

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 (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <input {...register('username')} />
      {errors.username && <span>{errors.username.message}</span>}
      <input {...register('password')} />
      {errors.password && <span>{errors.password.message}</span>}
      <button type="submit">submit</button>
    </form>
  );
};

TypeBox

JSON Schema Type Builder with Static Type Resolution for TypeScript

npm

With ValueCheck
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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('username')} />
      <input type="password" {...register('password')} />
      <input type="submit" />
    </form>
  );
};
With TypeCompiler

A high-performance JIT of TypeBox, read more

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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('username')} />
      <input type="password" {...register('password')} />
      <input type="submit" />
    </form>
  );
};
Custom/third-party types (e.g. ElysiaJS's t.Files())

typeboxResolver validates using @sinclair/typebox's own Value.Errors/Value.Check, so any schema Kind not built into TypeBox (custom types, or ones defined by a third-party library such as ElysiaJS) must be registered with TypeBox's own TypeRegistry (and FormatRegistry for string formats) before it's used — this is a TypeBox-level extension point, not something @hookform/resolvers wraps or needs to expose separately:

import { TypeRegistry } from '@sinclair/typebox';

if (!TypeRegistry.Has('Files')) {
  TypeRegistry.Set('Files', (schema, value) => Array.isArray(value));
}

Make sure this registration runs against the same @sinclair/typebox module instance the schema was built with — if a library vendors its own copy of @sinclair/typebox instead of relying on the shared peer dependency, its registrations won't be visible here, and you'll see a runtime "Unknown type" error.

ArkType

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

npm

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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('username')} />
      <input type="password" {...register('password')} />
      <input type="submit" />
    </form>
  );
};

Valibot

The modular and type safe schema library for validating structural data

npm

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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('username')} />
      <input type="password" {...register('password')} />
      <input type="submit" />
    </form>
  );
};

⚠️ If your schema uses v.transform(...) (or v.pipe(..., v.transform(...))) on a field, that field's parsed output type can differ from what the user actually types (its input type) — e.g. a string input transformed into a number. Passing a single generic to useForm<T> pins both the submitted values and the handleSubmit payload to that one type, which conflicts with valibotResolver, since it infers input and output separately. Either omit the generic and let it infer from resolver, or specify all three explicitly:

const schema = v.object({
  name: v.string(),
  number: v.pipe(v.string(), v.transform(Number)),
});

useForm<v.InferInput<typeof schema>, unknown, v.InferOutput<typeof schema>>({
  resolver: valibotResolver(schema),
});

TypeSchema

Universal adapter for schema validation, compatible with any validation library

npm

import { useForm } from 'react-hook-form';
import { typeschemaResolver } from '@hookform/resolvers/typeschema';
import { 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 (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('username')} />
      <input type="password" {...register('password')} />
      <input type="submit" />
    </form>
  );
};

effect-ts

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

npm

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

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

type FormData = typeof 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<FormData>({
    resolver: effectTsResolver(schema),
  });

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('username')} />
      {errors.username && <span role="alert">{errors.username.message}</span>}

      <input {...register('password')} />
      {errors.password && <span role="alert">{errors.password.message}</span>}

      <button type="submit">submit</button>
    </form>
  );
}

VineJS

VineJS is a form data validation library for Node.js

npm

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

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

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

  return (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('username')} />
      {errors.username && <span role="alert">{errors.username.message}</span>}
      <input {...register('password')} />
      {errors.password && <span role="alert">{errors.password.message}</span>}
      <button type="submit">submit</button>
    </form>
  );
};

fluentvalidation-ts

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

npm

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

class FormDataValidator extends Validator<FormData> {
  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,
    formState: { errors },
  } = useForm({
    resolver: fluentValidationResolver(new FormDataValidator()),
  });

  return (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('username')} />
      {errors.username && <span role="alert">{errors.username.message}</span>}
      <input {...register('password')} />
      {errors.password && <span role="alert">{errors.password.message}</span>}
      <button type="submit">submit</button>
    </form>
  );
};

standard-schema

A standard interface for TypeScript schema validation libraries

npm

Example zod

import { useForm } from 'react-hook-form';
import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';
import { 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: standardSchemaResolver(schema),
  });

  return (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('name')} />
      {errors.name?.message && <p>{errors.name?.message}</p>}
      <input type="number" {...register('age', { valueAsNumber: true })} />
      {errors.age?.message && <p>{errors.age?.message}</p>}
      <input type="submit" />
    </form>
  );
};

Example arkType

import { useForm } from 'react-hook-form';
import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';
import { type } from 'arktype';

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

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

  return (
    <form onSubmit={handleSubmit((d) => console.log(d))}>
      <input {...register('username')} />
      <input type="password" {...register('password')} />
      <input type="submit" />
    </form>
  );
};

ata-validator

A JSON Schema-based validator for JavaScript and TypeScript

npm

import { useForm } from 'react-hook-form';
import { ataResolver } from '@hookform/resolvers/ata-validator';

const schema = {
  type: 'object',
  properties: {
    username: {
      type: 'string',
      minLength: 1,
    },
    password: {
      type: 'string',
      minLength: 1,
    },
  },
  required: ['username', 'password'],
};

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

  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <input {...register('username')} />
      {errors.username && <span>{errors.username.message}</span>}
      <input {...register('password')} />
      {errors.password && <span>{errors.password.message}</span>}
      <button type="submit">submit</button>
    </form>
  );
};

Backers

Thanks go to all our backers! [Become a backer].

React Hook Form backers

Contributors

Thanks go to these wonderful people! [Become a contributor].

FAQ

What is @hookform/resolvers used for?

React Hook Form validation resolvers: Yup, Joi, Superstruct, Zod, Vest, Class Validator, io-ts, Nope, computed-types, TypeBox, arktype, Typanion, Effect-TS and VineJS

How can I tell if a website is using @hookform/resolvers?

Open the page in Chrome with the Sourcemap Explorer extension installed and read the Stack tab. We catch `@hookform/resolvers` from two complementary signals: `node_modules/@hookform/resolvers/` paths inside the JavaScript sourcemap, and the embedded `package.json` we read for exact-version detection. Without the extension you can do the same lookup manually in DevTools — the steps are listed in the "How Sourcemap Explorer detects" section above.

How do I find out which version of @hookform/resolvers a website is running?

Read it straight from the site's JavaScript sourcemap. When a build ships source maps, the bundled `@hookform/resolvers/package.json` carries the exact `version` string — Sourcemap Explorer extracts it in one click on the Stack tab, and you can do it by hand in DevTools by opening the `.map` file and searching for `node_modules/@hookform/resolvers/package.json`. That is far more reliable than inferring the version from an asset-hash or a `?ver=` query string, which is all surface-level detectors have to go on. The current npm release is 5.7.1, but real deployments frequently run an older pinned version — which is exactly why reading the bundled number matters.

What is the latest version of @hookform/resolvers?

5.7.1, as published on the npm registry. The "Recent versions" table on this page lists the most recent 8 releases with their release dates. Sourcemap Explorer reports the version actually bundled into a site, which can lag the latest release by months on real-world deployments.

Is @hookform/resolvers actively maintained?

Very actively maintained — the last release shipped within the past three months. The last published release was 2026-08-02. Source code: https://github.com/react-hook-form/resolvers.

Where can I read more?

Project homepage: https://react-hook-form.com. Source code: https://github.com/react-hook-form/resolvers. Published on npm: https://www.npmjs.com/package/@hookform/resolvers. Licensed as MIT.

Keep reading on Sourcemap Explorer

Detection deep dives

Detected by Sourcemap Explorer

When a bundle ships sourcemaps, we read the embedded package.json for @hookform/resolvers and report the precise version (the registry's latest is v5.7.1, published 2026-08-02; the bundled copy is often older). Without sourcemaps, an import / require in the page's scripts is enough to flag it.

Install free on Chrome