Decision. Default stack for a new React app in 2026: React Hook Form 7.81 [1] + Zod 4 [2] + your UI kit’s engine-agnostic
Fieldprimitives [3], with React’suseActionStateowning only the submit round-trip [4]. Reach for TanStack Form when you need one form core across frameworks or genuinely deep typed paths [5]; reach for Conform when the form must work before hydration [6].
The single most consequential finding is a negative one: React’s form APIs stopped moving. Everything form-related shipped in React 19.0 (Dec 2024) — <form action>, useActionState, useFormStatus, useOptimistic [7] — and 19.1/19.2 added nothing to that surface [8]. What shipped is a complete submission layer and an empty form layer: no field-level validation, no dirty tracking, no field arrays. Worse, an uncontrolled form is auto-cleared after a form action even when the action returns a validation error, and the tracking issue for it was closed as not planned [9]. So the 2026 shape is library owns the client, Action owns the wire — and the seam between them is not well supported: pairing RHF with useActionState in the App Router still needs a timestamp-field hack to force state through [10], and RHF’s maintainers have taken no official position on Server Actions at all [11].
Meanwhile the layer below the form got commoditised. Standard Schema v1.1 gave every validator a common ~standard interface [12], and the form libraries consume it: TanStack Form natively [13], RHF through @hookform/resolvers’ generic standardSchemaResolver [14] — even Yup 1.7 and Joi 18 now implement it [15]. The validator is therefore a swappable dependency at the form boundary, but not at the ORM/RPC boundary, which is why Zod (≈224M weekly downloads — more than React itself) stays the default for one-schema-client-and-server [2]. Note the irony for anyone bundle-shopping: Zod at ~62 kB min+gzip dwarfs every form library it is paired with [16], and RHF vs Formik is 12.87 vs 13.12 kB [17] — the “RHF is tiny” folklore is quoting 2022 versions.
Across the two hardest angles, one question turns out to generate all the others: where do the field values live? RHF keeps them in mutable refs (unmounted fields keep their value), TanStack Form in an external store (unmounted fields keep value and stale errors, which silently blocks submit [18]), Conform in the DOM (unmounted means deleted, unless wrapped in PreserveBoundary [19]). Conditional fields, wizards, field arrays and the re-render budget are all downstream of that one choice. The same question decides uploads: because a File never deep-equals itself, storing the upload key rather than the File is what keeps dirty-tracking sane [20] — and the bytes should never travel through the form anyway (Next.js caps Server Action bodies at 1 MB [21], and fetch still cannot report upload progress by design [22]).
Two open risks worth naming. RHF v7 is structurally incompatible with the React Compiler, and v8-beta’s headline feature is fixing exactly that [23] — so the safe default is on a beta migration path. And the App Router still has no first-party unsaved-changes guard; the request has been open since March 2023 [24], while React Router 7 and TanStack Router both solved it [25]. If you are choosing a router for a form-heavy app, that gap is a real input to the decision.