Skip to content

React — Checklists

OWNER: floris, floor ALSO_USED_BY: alexander, tobias LAST_VERIFIED: 2026-03-26 GE_STACK_VERSION: React 19.x


Overview

Machine-parseable checklists for component quality, accessibility, and performance. Run through these before marking a component as complete.


COMPONENT QUALITY CHECKLIST (every component)

  • [ ] CHECK: component has explicit TypeScript return type
  • [ ] CHECK: props interface is exported and named {Component}Props
  • [ ] CHECK: no any types — unknown with type guards instead
  • [ ] CHECK: named export only — no default exports
  • [ ] CHECK: file is under 200 lines IF_SKIPPED: component becomes unmaintainable, extract hooks/sub-components
  • [ ] CHECK: one exported component per file
  • [ ] CHECK: no "use client" unless component uses hooks or event handlers IF_SKIPPED: entire subtree becomes client-rendered unnecessarily
  • [ ] CHECK: "use client" is at the smallest leaf, not a layout or page
  • [ ] CHECK: co-located test file exists (component-name.test.tsx)
  • [ ] CHECK: no inline style objects — Tailwind classes only
  • [ ] CHECK: conditional classes use cn() utility
  • [ ] CHECK: shadcn/ui used when a matching primitive exists

ACCESSIBILITY CHECKLIST (every interactive component)

  • [ ] CHECK: all form inputs have associated <label> elements IF_SKIPPED: screen readers cannot identify the input
  • [ ] CHECK: error messages use role="alert"
  • [ ] CHECK: interactive elements are keyboard accessible (Tab, Enter, Escape)
  • [ ] CHECK: images have alt text (empty alt="" for decorative images)
  • [ ] CHECK: buttons have visible text or aria-label
  • [ ] CHECK: aria-invalid is set on inputs with validation errors
  • [ ] CHECK: modals trap focus and return focus on close
  • [ ] CHECK: color is not the only indicator of state (add icon or text)
  • [ ] CHECK: heading hierarchy is logical (no skipping levels)
  • [ ] CHECK: custom components use appropriate ARIA roles IF_SKIPPED: assistive technology cannot interpret the component

PERFORMANCE CHECKLIST (components rendering lists or heavy data)

  • [ ] CHECK: lists with 50+ items use virtualization (tanstack-virtual or similar) IF_SKIPPED: renders all DOM nodes — sluggish on mobile
  • [ ] CHECK: no manual useMemo/useCallback if React Compiler is active
  • [ ] CHECK: images use Next.js <Image> with width/height or fill
  • [ ] CHECK: heavy components are lazy-loaded with React.lazy + Suspense
  • [ ] CHECK: no useEffect for data fetching — TanStack Query instead IF_SKIPPED: no caching, no dedup, race conditions
  • [ ] CHECK: key prop uses stable unique ID, not array index IF_SKIPPED: reorder/delete corrupts component state
  • [ ] CHECK: context values are memoized to prevent cascade re-renders
  • [ ] CHECK: derived state is computed during render, not synced via useEffect IF_SKIPPED: unnecessary extra render cycle
  • [ ] CHECK: no inline object/function props to memoized children IF_SKIPPED: memo is bypassed on every render

FORM CHECKLIST (every form component)

  • [ ] CHECK: uses React Hook Form with zodResolver
  • [ ] CHECK: Zod schema is shared between client and Server Action
  • [ ] CHECK: Server Action uses safeParse, not parse
  • [ ] CHECK: validation mode is onBlur
  • [ ] CHECK: submit button disabled during submission
  • [ ] CHECK: field errors render below the field with role="alert"
  • [ ] CHECK: server errors (non-field) render at the top of the form
  • [ ] CHECK: uses .issues not .errors on ZodError (Zod v4) IF_SKIPPED: error display silently breaks ADDED_FROM: ge-admin-ui-2026-02, Zod v4 migration

Cross-References

READ_ALSO: wiki/docs/stack/react/index.md READ_ALSO: wiki/docs/stack/react/pitfalls.md READ_ALSO: wiki/docs/stack/react/forms.md READ_ALSO: wiki/docs/stack/react/patterns.md