Using Formik and React Hook Form in React – Best Form Libraries (2025)

Forms are an essential part of any React application — from login screens to multi-step registrations.
However, manually managing state, validation, and submission logic can quickly become messy.

That’s where form libraries like Formik and React Hook Form make development cleaner, faster, and more scalable.

In this lesson, you’ll learn:

  • What Formik and React Hook Form are
  • How to use each one step-by-step
  • Their pros, cons, and differences

What is Formik?

Formik is a form management library for React that helps handle:

  • Form state (values, touched fields, errors)

  • Validation (manual or with Yup)

  • Submission logic

Formik keeps your code organized and reduces repetitive state management.

Installation

 
npm install formik yup

Example: Formik + Yup Validation

import React from "react";
import { useFormik } from "formik";
import * as Yup from "yup";

function FormikExample() {
  const formik = useFormik({
    initialValues: {
      name: "",
      email: "",
    },
    validationSchema: Yup.object({
      name: Yup.string()
        .min(2, "Name must be at least 2 characters")
        .required("Name is required"),
      email: Yup.string()
        .email("Invalid email address")
        .required("Email is required"),
    }),
    onSubmit: (values) => {
      alert(JSON.stringify(values, null, 2));
    },
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <div>
        <label>Name:</label>
        <input
          name="name"
          value={formik.values.name}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
        {formik.touched.name && formik.errors.name && (
          <p style={{ color: "red" }}>{formik.errors.name}</p>
        )}
      </div>

      <div>
        <label>Email:</label>
        <input
          name="email"
          value={formik.values.email}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
        {formik.touched.email && formik.errors.email && (
          <p style={{ color: "red" }}>{formik.errors.email}</p>
        )}
      </div>

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

export default FormikExample;

Why Use Formik?

  • Handles form state and validation automatically
  • Integrates seamlessly with Yup for schema-based validation
  • Reduces repetitive useState and onChange logic
  • Easy to debug and maintain

What is React Hook Form?

React Hook Form (RHF) is a lightweight form library built around React Hooks.
It offers better performance by registering inputs directly and avoiding unnecessary re-renders.

 Installation

 
npm install react-hook-form

Example: Basic Form with Validation

import React from "react";
import { useForm } from "react-hook-form";

function RHFExample() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const onSubmit = (data) => alert(JSON.stringify(data, null, 2));

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div>
        <label>Name:</label>
        <input
          {...register("name", { required: "Name is required", minLength: 2 })}
        />
        {errors.name && <p style={{ color: "red" }}>{errors.name.message}</p>}
      </div>

      <div>
        <label>Email:</label>
        <input
          {...register("email", {
            required: "Email is required",
            pattern: { value: /\S+@\S+\.\S+/, message: "Invalid email" },
          })}
        />
        {errors.email && <p style={{ color: "red" }}>{errors.email.message}</p>}
      </div>

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

export default RHFExample;

Why Use React Hook Form?

  • Minimal re-renders → faster performance
  • Small library size (tiny bundle footprint)
  • Works with uncontrolled components (via refs)
  • Simple validation syntax without extra libraries
  • Great for large or high-performance apps

Formik vs React Hook Form

Feature / AspectFormikReact Hook Form
Form ManagementControlled (uses React state)Uncontrolled (uses refs)
PerformanceSlightly slower (re-renders on change)Very fast (minimal re-renders)
ValidationSchema-based (via Yup)Built-in or custom rules
Ease of UseBeginner-friendlySimple but different API
Bundle SizeLarger (~15 KB)Smaller (~8 KB)
Best ForComplex enterprise formsLightweight, high-speed forms

Using Yup with React Hook Form

You can combine RHF with Yup for advanced schema validation using @hookform/resolvers.

Install Resolver

 
npm install @hookform/resolvers yup

Example

import React from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as Yup from "yup";

function RHFYupExample() {
  const validationSchema = Yup.object().shape({
    username: Yup.string().required("Username is required"),
    age: Yup.number().positive().integer().required("Age is required"),
  });

  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({ resolver: yupResolver(validationSchema) });

  const onSubmit = (data) => alert(JSON.stringify(data, null, 2));

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label>Username:</label>
      <input {...register("username")} />
      {errors.username && <p style={{ color: "red" }}>{errors.username.message}</p>}

      <label>Age:</label>
      <input type="number" {...register("age")} />
      {errors.age && <p style={{ color: "red" }}>{errors.age.message}</p>}

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

export default RHFYupExample;

Best Practices

Use Formik when:

  • You need complex nested forms

  • You rely heavily on Yup schemas

  • You prefer a controlled component approach

 Use React Hook Form when:

  • You want lightweight, fast, and scalable performance

  • You work with many inputs or dynamic forms

  • You prefer uncontrolled components