Technical Reference for Frontend Engineers
JavaScript Form Validation & UX Patterns
A deep-dive technical resource covering async validation, HTML5 constraint APIs, Zod schema design, ARIA accessibility, and production-ready UX error patterns — all with TypeScript examples.
Form validation is one of the most deceptively complex challenges in frontend
engineering. Beyond a simple required attribute, production systems must
handle race conditions in async server checks, cross-field dependencies, WCAG 2.2
accessibility requirements, and stateful error recovery — all without degrading
perceived performance.
This site provides implementation-ready patterns covering the full validation stack: from native browser APIs and Zod schema composition to ARIA live region orchestration and micro-interaction design. Every example is written in TypeScript and validated against real-world edge cases.
Whether you are modernising a legacy form system, building a design system's input components, or hardening a multi-step checkout flow, the sections below guide you from declarative HTML constraints up through architectural-level validation engines, field-by-field recipes for passwords, cards, phones and dates, server-side validation, framework integration, and testing with tools and screen readers — now spanning more than 180 in-depth guides with task-focused recipes for React Hook Form, VeeValidate, Angular, SvelteKit, TanStack Form, Zod, Valibot, Playwright, Vitest and axe-core.
What You'll Learn
Advanced JavaScript Validation
Async validators with AbortController, finite state machines, Zod schemas, cross-field DAG resolution, and event delegation patterns.
- Async Server Checks
- Schema-Based Validation (Zod)
- Cross-Field Strategies
- Sync Validation Patterns
- Form State Machines
- Dynamic & Repeating Fields
- Valibot, Yup & Other Schemas
HTML5 Native Validation
Master the Constraint Validation API: checkValidity(), reportValidity(), setCustomValidity(), input types, pattern attributes, and the form submission lifecycle.
- Constraint Validation API
- Custom Validity Messages
- Form Submission Lifecycle
- HTML5 Input Attributes
- Styling with :user-invalid
- Form-Associated Custom Elements
Validating Common Input Types
Field-by-field recipes for the inputs every product has: passwords, card numbers with Luhn checks, international phone numbers and postcodes, dates, file uploads and names.
- Password Validation
- Payment Cards & IBAN
- Phone & Address
- Dates & Times
- File Uploads
- Names & Identity Fields
UX & Error State Design
WCAG-compliant error states, inline messaging timing, focus management, progressive disclosure, and accessible toast notification patterns with live regions.
- Inline Error Messaging
- Focus & Keyboard Navigation
- Visual Feedback & Micro-interactions
- Progressive Disclosure
- Mobile Validation UX
- Success States
Framework Integration
Wire native constraint validation into React Hook Form, Vue VeeValidate, Angular Reactive Forms, Svelte, TanStack Form and Formik — resolvers, async validators, and cross-field rules mapped back to the Constraint Validation API.
- React Hook Form
- Vue VeeValidate
- Angular Reactive Forms
- Svelte & SvelteKit
- TanStack Form
- Formik & Yup
Server & Full-Stack Validation
Validation across the network boundary: one schema for client and server, consistent API error responses, progressively enhanced server actions, and the rate limits and bot defences forms rely on.
Explore Server-SideTesting & Accessibility
Automate axe-core audits, assert aria-invalid and error wiring with Playwright, and unit test validators with Vitest, listen with NVDA and VoiceOver, and ship to WCAG 2.2 Success Criteria 3.3.x.
- axe-core Audits
- Playwright Form Tests
- WCAG 2.2 Checklists
- Unit Testing Validators
- Screen Reader Testing
Core Patterns at a Glance
AbortController Async
Cancel stale network requests on each keystroke to prevent race conditions and UI flicker in real-time field validation.
Finite State Machine
Model validators as 'idle' | 'pending' | 'resolved' | 'rejected' | 'cancelled' to eliminate impossible UI states.
Event Delegation
Bind a single listener to a stable container rather than per-field to prevent memory leaks in dynamic forms.
ARIA Trio
Always pair aria-invalid="true" + aria-describedby + role="alert" for screen-reader-accessible error states.
Zod Schema Composition
Build type-safe validators with z.object().extend() and map ZodError instances to accessible UI error maps.
Pre-compiled RegExp
Define regex constants outside functions to avoid GC pressure. Use .test() for boolean checks — never .match() inside hot paths.