Form validation is the first line of defense for your application data. Get it wrong and you are dealing with garbage inputs, security vulnerabilities, and frustrated users. This guide covers client-side validation with modern JavaScript, from native browser APIs to popular validation patterns that actually work in production.
Native HTML5 Validation
Before reaching for JavaScript, use what the browser gives you for free. HTML5 validation attributes handle the most common cases with zero JavaScript: required, type="email", minlength, maxlength, pattern, and min/max for numbers. The browser displays native error messages and prevents form submission when constraints are violated.
The Constraint Validation API
The Constraint Validation API gives you JavaScript control over HTML5 validation. Key methods include checkValidity() to test a field or form, reportValidity() to show validation messages, and setCustomValidity() to set custom error messages. The validity property provides detailed state information like valueMissing, typeMismatch, patternMismatch, and tooShort.
Custom Validation with JavaScript
For complex rules that HTML5 cannot express, write custom validators. Common patterns include password confirmation matching, conditional required fields, cross-field validation (end date after start date), and async validation like checking username availability.
Real-Time vs Submit Validation
Validate on blur (when the user leaves a field) for individual field rules. Validate on submit for cross-field rules and final confirmation. Avoid validating on every keystroke – it creates a hostile experience when the form shows errors before the user has finished typing. The exception is password strength meters, which benefit from real-time feedback.
Validation Libraries
For complex forms, validation libraries save time:
- Zod – TypeScript-first schema validation, excellent for form data and API payloads
- Yup – Schema-based validation popular with Formik and React Hook Form
- Vest – Unit-test-inspired validation framework with excellent async support
- VeeValidate – Vue.js focused validation with composition API support
Server-Side Validation
Client-side validation improves user experience. Server-side validation provides security. Never skip server-side validation – client-side checks can be bypassed by anyone with browser dev tools. Validate all inputs on the server using the same rules, sanitize data for SQL injection and XSS, and return structured error responses that the client can display.
Accessibility
Validation errors must be accessible. Use aria-describedby to connect error messages to their fields. Set aria-invalid="true" on invalid fields. Use role="alert" on error message containers so screen readers announce them. Test your forms with a keyboard only – tab order, focus management after errors, and error message visibility all matter. See our regex guide for validation patterns.