18
Forms in depth

Forms in depth

Beyond the input element — the patterns that turn forms from rage-bait into the part of the product users trust.

~ 170 min·11 lessons·updated may 2026

What you'll learn


Lessons

Read in order. Each lesson stands on its own, but the order is deliberate.

11 lessons · ~157 min total

  1. 01
    Controlled vs uncontrolled
    What "controlled" really means, and which inputs deserve it.
    14 min
  2. 02
    Form state, sized to fit
    useState, lifted state, libraries — pick the smallest that fits.
    15 min
  3. 03
    Validation timing
    onSubmit, onBlur, onChange — and the rule for when each fires.
    14 min
  4. 04
    Schema validation
    Zod, Valibot, Yup — one schema, two purposes (parse and validate).
    16 min
  5. 05
    Async validation, without races
    Debouncing, latest-wins, and the AbortController pattern.
    15 min
  6. 06
    Error messages that help
    What good copy looks like, where it goes, and accessibility.
    13 min
  7. 07
    Multi-step forms
    Wizards, persistence, going back without losing state.
    14 min
  8. 08
    File uploads
    Single, multiple, drag-and-drop, progress, and resumable uploads.
    15 min
  9. 09
    Form libraries vs hand-rolled
    react-hook-form, Formik, TanStack Form — when each is worth it.
    13 min
  10. 10
    Submission UX
    Pending states, optimistic updates, and what to do on failure.
    14 min
  11. 11
    Forms and Server Actions
    Progressive enhancement, useActionState, and the JS-off path.
    14 min

Prerequisites

  • · Built a form that does more than alert("Submitted!")
  • · Comfortable with React (or another component framework)

After this, try