Formik 34,320 (github.com/jaredpalmer/formik (https://github.com/jaredpalmer/formik 34,320 ), Apache-2.0, npm 2,036 install formik yup) was the form library for years and still fills a great deal of production code. It keeps values, errors and touched for you, runs a validation schema, and exposes the result through a render prop or through useFormik. Version 2.4.9 dates from November 2025; the project is maintained rather than developed, so treat it as a library you inherit, not one you start with.
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
const schema = Yup.object({ email: Yup.string().email().required('Email is required') });
const send = (values) => fetch('https://api.example.com/contact', { method: 'POST' });
export default function Contact() {
return (
<Formik initialValues={{ email: '' }} validationSchema={schema} onSubmit={send}>
{({ isSubmitting }) => (
<Form>
<Field name="email" type="email" />
<ErrorMessage name="email" component="p" />
<button disabled={isSubmitting}>Send</button>
</Form>)}
</Formik>);
}<Field> wires value, onChange and onBlur by name; <Form> is a <form> with onSubmit already bound. Everything lives in React 7,897 state, so every keystroke re-renders the subtree under <Formik> — the reason <FastField> exists, and the reason React Hook Form exists.