Skip to main content

At most one form library

ab-000220 · ai-slop-code-drift.ui-stack-drift.dual-form-library
Severity: highactive

Why it matters

Two form libraries mean two validation APIs, two error-display conventions, and two mental models for managing touched/dirty/submitting state. Developers copy-paste the wrong pattern, accessibility attributes drift between screens, and form-level test helpers multiply. Users experience inconsistent error messaging and focus behavior across forms, and your bundle ships both runtimes to every page even when only one is used on that route.

Severity rationale

High because inconsistent form behavior directly erodes accessibility compliance and user trust during critical conversion flows.

Remediation

Consolidate on one library, typically react-hook-form for shadcn projects. Run grep -rl "from 'formik'" src/ to enumerate every holdout, then rewrite each form component to the canonical pattern. Remove the loser with npm uninstall formik. Keep a reference implementation in src/components/forms/example-form.tsx that future contributors can copy, and delete any legacy resolver adapters from package.json once the migration is complete.

Detection

  • ID: ai-slop-code-drift.ui-stack-drift.dual-form-library

  • Severity: high

  • What to look for: Apply the three-condition rule against this exact form library allowlist: react-hook-form, formik, final-form, react-final-form, tanstack-form, @tanstack/react-form, react-hook-form-mui, unform, @conform-to/react. EXCEPT: if the project uses shadcn-ui (presence of components.json) AND react-hook-form is the only form library, that's the canonical shadcn pattern — pass. Count all package names found and report the file count for each.

  • Pass criteria: 0 or 1 form libraries from the allowlist actively used. Report even on pass: "Canonical form library: [name] ([N] importing files)."

  • Fail criteria: 2 or more form libraries from the allowlist meet all three conditions (at least 1 non-escape-hatch importing file).

  • Skip (N/A) when: 0 form libraries from the allowlist appear in RUNTIME_DEPS.

  • Detail on fail: "2 active form libraries: 'react-hook-form' (12 files) AND 'formik' (5 files). Pick one — every form should follow the same pattern."

  • Remediation: Two form libraries means two patterns for validation, two sets of error displays, two state-management approaches per form. Pick one and migrate:

    # Find every formik usage
    grep -rl "from 'formik'" src/
    
    # Convert each form to react-hook-form
    npm uninstall formik
    

    For shadcn projects, react-hook-form is the canonical choice — keep it and remove others.

Taxons

History