Registry / web-framework / react-hook-form

react-hook-form

JSON →
library7.72.1jsnpmunverified

React Hook Form is a high-performance, flexible, and extensible forms library for React applications, currently stable at version 7.72.1. It leverages an uncontrolled component approach, minimizing re-renders and improving performance by isolating component updates from form state changes. The library maintains a rapid release cadence, frequently delivering patches and minor versions, with a beta for version 8 already available. Key differentiators include its focus on performance, small bundle size, seamless integration with native HTML form validation, and robust TypeScript support for enhanced type safety across form values and errors. It provides essential hooks like `useForm` for comprehensive form management, `Controller` for integrating with external controlled components, and `useFieldArray` for dynamic lists of inputs, making it suitable for a wide spectrum of form complexities.

npm install react-hook-form
INSTALL
IMPORT
SIG · REACT-HOOK-FORM
R
react-hook-form
web-frameworkjavascriptv7.72.1
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

useForm
import { useForm } from 'react-hook-form';
const { useForm } = require('react-hook-form');
The primary hook for form management. Destructure directly from the import. CommonJS `require` is deprecated for modern React applications using ESM.
Controller
import { Controller } from 'react-hook-form';
import Controller from 'react-hook-form/dist/Controller';
Used for integrating controlled components from UI libraries (e.g., Material-UI, Ant Design). It acts as a wrapper. No default export.
useFieldArray
import { useFieldArray } from 'react-hook-form';
import { UseFieldArray } from 'react-hook-form';
Hook for managing dynamic forms (e.g., lists of items). Ensure correct capitalization.
FormProvider
import { FormProvider } from 'react-hook-form';
Provides form context to deeply nested components, avoiding prop drilling.

This quickstart demonstrates a basic form using `useForm` with TypeScript, `register` for input binding and validation, `handleSubmit` for submission, and `formState.errors` for displaying validation feedback. It includes required fields, email pattern validation, and minimum age constraint.

import React from 'react'; import { useForm } from 'react-hook-form'; type FormData = { firstName: string; lastName: string; email: string; age: number; }; export default function MyForm() { const { register, handleSubmit, formState: { errors }, } = useForm<FormData>({ defaultValues: { firstName: '', lastName: '', email: '', age: 18, }, }); const onSubmit = (data: FormData) => { console.log('Form Submitted:', data); // In a real app, you would send this data to an API // Example: fetch('/api/submit-form', { method: 'POST', body: JSON.stringify(data) }); alert(JSON.stringify(data, null, 2)); }; return ( <form onSubmit={handleSubmit(onSubmit)} className="space-y-4 p-4 max-w-md mx-auto bg-white shadow-md rounded-lg"> <div> <label htmlFor="firstName" className="block text-sm font-medium text-gray-700">First Name:</label> <input id="firstName" {...register('firstName', { required: 'First name is required' })} className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" /> {errors.firstName && <p className="mt-1 text-sm text-red-600">{errors.firstName.message}</p>} </div> <div> <label htmlFor="lastName" className="block text-sm font-medium text-gray-700">Last Name:</label> <input id="lastName" {...register('lastName', { required: 'Last name is required' })} className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" /> {errors.lastName && <p className="mt-1 text-sm text-red-600">{errors.lastName.message}</p>} </div> <div> <label htmlFor="email" className="block text-sm font-medium text-gray-700">Email:</label> <input id="email" type="email" {...register('email', { required: 'Email is required', pattern: { value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i, message: 'Invalid email address' } })} className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" /> {errors.email && <p className="mt-1 text-sm text-red-600">{errors.email.message}</p>} </div> <div> <label htmlFor="age" className="block text-sm font-medium text-gray-700">Age:</label> <input id="age" type="number" {...register('age', { required: 'Age is required', min: { value: 18, message: 'Must be at least 18' } })} className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" /> {errors.age && <p className="mt-1 text-sm text-red-600">{errors.age.message}</p>} </div> <button type="submit" className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" > Submit </button> </form> ); }
Debug
Known issues
breakingVersion 8.0.0-beta.1 introduces breaking changes: `register` now expects an input `ref` directly instead of a partial object. The `useFieldArray` hook has renamed its `id` property to `key` and removed the `keyName` prop.
fix
For `register`, pass the input's `ref` directly. For `useFieldArray`, update usage from `id` to `key` and remove `keyName`. Refer to the v8 migration guide for detailed instructions on `setValue` changes as well.
affects: >=8.0.0-beta.1
breakingCritical RCE (Remote Code Execution) vulnerabilities (CVE-2025-55182, CVE-2025-55183, CVE-2025-55184, CVE-2025-67779) were listed in v7.69.0. While the specific impact on `react-hook-form` is not fully detailed in the provided excerpt, such CVEs in dependencies or related ecosystems (like React Server Components as mentioned in general CVE discussions) can indicate severe security risks. Users should prioritize updating and reviewing their dependency tree.
fix
Upgrade to the latest patch version (7.72.1 or newer) immediately to ensure all known security fixes are applied. Monitor official `react-hook-form` releases and security advisories for further guidance.
affects: 7.69.0
gotchaWhen using `setValue` with `shouldDirty` (or when relying on `isDirty` with numeric string keys in `defaultValues`), older versions may incorrectly mark unrelated fields as dirty or fail to correctly track dirtiness. This can lead to unexpected form state behavior.
fix
Upgrade to `react-hook-form@7.72.1` or newer. If on an older version, manually manage dirty state for complex scenarios or ensure `defaultValues` are correctly structured and used.
affects: <7.72.1
gotchaProviding `defaultValues` to `useForm` is crucial for `isDirty` and `dirtyFields` to work correctly. Without `defaultValues`, the library has no baseline to compare against, leading to `isDirty` always being `false` or `dirtyFields` being empty even after user interaction.
fix
Always pass a complete `defaultValues` object to the `useForm` hook, ensuring it reflects the initial state of all registered inputs.
affects: >=7.0.0
Errors
Common errors & fixes
TypeError: Cannot read properties of undefined (reading '_f')
This error often occurs when attempting to access internal `_f` property of a field that hasn't been properly registered with `react-hook-form` or has been unmounted. It can also happen when `Controller` or `useFieldArray` are misused or when the `control` object is not propagated correctly.
fix
Ensure all input fields are correctly registered using `register` or wrapped with `Controller`. Verify that the `control` object from `useForm` is passed down to `Controller` and `useFieldArray` components, especially in nested contexts or when using `FormProvider`. Check for any conditional rendering that might unmount fields unexpectedly without proper unregistration handling.
formState.isValid incorrect on Controller re-mount
In specific scenarios, `formState.isValid` may not update correctly when a `Controller`-managed component re-mounts, leading to an inaccurate validation status of the form.
fix
This specific issue was addressed in `v7.72.1`. Upgrade to `react-hook-form@7.72.1` or a newer version to receive the fix.
Field array ghost elements with keepDirtyValues
Older versions of `useFieldArray` could sometimes produce 'ghost' elements or exhibit incorrect dirty state behavior when `keepDirtyValues` was enabled, especially after manipulation (append, remove, etc.).
fix
This was addressed in `v7.70.0`. Update to `react-hook-form@7.70.0` or a newer version to resolve issues with field array ghost elements and `keepDirtyValues`.
The first keystroke is not working, or input value is reset.
This typically happens if you are mistakenly using the `value` prop directly on an uncontrolled input that `react-hook-form` manages, instead of `defaultValue`. `React Hook Form` relies on uncontrolled inputs, where it reads the initial value from `defaultValue` and then tracks changes internally, not through React state for every keystroke.
fix
Replace `value="..."` with `defaultValue="..."` for initial values on your inputs registered with `react-hook-form`. Avoid using `value` for managed inputs unless you are specifically working with controlled components via `Controller`.
Upgrade
Version history
7.72.1latest on npm
Audit
Dependencies
reactrequiredPeer dependency required for React applications.
Agent activity
7 hits · last 30 days
node
6
Resources
react-hook-form — npm install react-hook-form · libregistry