How to validate password strength in React

Validating password strength in React ensures users create secure passwords by implementing multiple security criteria with real-time feedback and visual strength indicators. As the creator of CoreUI with extensive React experience since 2014, I’ve built password validation systems for enterprise applications requiring robust security standards and user guidance. The most effective approach uses multiple validation rules with dynamic scoring and visual feedback to guide users toward creating strong, secure passwords. This method provides comprehensive security validation while maintaining excellent user experience through progressive disclosure and helpful feedback.

Implement multi-criteria password validation with real-time strength scoring and visual feedback indicators for secure password creation.

import { useState, useMemo } from 'react'

const PasswordStrengthValidator = () => {
    const [password, setPassword] = useState('')
    const [showPassword, setShowPassword] = useState(false)

    const passwordValidation = useMemo(() => {
        const criteria = {
            minLength: password.length >= 8,
            hasUppercase: /[A-Z]/.test(password),
            hasLowercase: /[a-z]/.test(password),
            hasNumber: /\d/.test(password),
            hasSpecialChar: /[!@#$%^&*(),.?":{}|<>]/.test(password),
            noSpaces: !/\s/.test(password)
        }

        const score = Object.values(criteria).filter(Boolean).length
        const maxScore = Object.keys(criteria).length

        let strength = 'Very Weak'
        let color = '#dc3545'

        if (score >= 5) {
            strength = 'Strong'
            color = '#28a745'
        } else if (score >= 4) {
            strength = 'Good'
            color = '#ffc107'
        } else if (score >= 2) {
            strength = 'Fair'
            color = '#fd7e14'
        } else if (score >= 1) {
            strength = 'Weak'
            color = '#dc3545'
        }

        return {
            criteria,
            score,
            maxScore,
            strength,
            color,
            isValid: score >= 4
        }
    }, [password])

    const handleSubmit = (e) => {
        e.preventDefault()
        if (passwordValidation.isValid) {
            console.log('Password is strong enough')
            // Process form submission
        }
    }

    return (
        <form onSubmit={handleSubmit}>
            <div className="form-group">
                <label htmlFor="password">Password</label>
                <div className="input-group">
                    <input
                        id="password"
                        type={showPassword ? 'text' : 'password'}
                        value={password}
                        onChange={(e) => setPassword(e.target.value)}
                        className="form-control"
                        placeholder="Enter your password"
                    />
                    <button
                        type="button"
                        className="btn btn-outline-secondary"
                        onClick={() => setShowPassword(!showPassword)}
                    >
                        {showPassword ? 'Hide' : 'Show'}
                    </button>
                </div>

                {password && (
                    <div className="mt-2">
                        <div className="d-flex justify-content-between mb-1">
                            <small>Password Strength:</small>
                            <small style={{ color: passwordValidation.color, fontWeight: 'bold' }}>
                                {passwordValidation.strength}
                            </small>
                        </div>
                        <div className="progress mb-2">
                            <div
                                className="progress-bar"
                                style={{
                                    width: `${(passwordValidation.score / passwordValidation.maxScore) * 100}%`,
                                    backgroundColor: passwordValidation.color
                                }}
                            />
                        </div>

                        <div className="password-criteria">
                            {Object.entries({
                                'At least 8 characters': passwordValidation.criteria.minLength,
                                'Uppercase letter (A-Z)': passwordValidation.criteria.hasUppercase,
                                'Lowercase letter (a-z)': passwordValidation.criteria.hasLowercase,
                                'Number (0-9)': passwordValidation.criteria.hasNumber,
                                'Special character (!@#$%^&*)': passwordValidation.criteria.hasSpecialChar,
                                'No spaces': passwordValidation.criteria.noSpaces
                            }).map(([rule, valid]) => (
                                <div
                                    key={rule}
                                    className={`small ${valid ? 'text-success' : 'text-muted'}`}
                                >
                                    {valid ? '✓' : '○'} {rule}
                                </div>
                            ))}
                        </div>
                    </div>
                )}
            </div>

            <button
                type="submit"
                className="btn btn-primary"
                disabled={!passwordValidation.isValid}
            >
                Create Account
            </button>
        </form>
    )
}

This code implements comprehensive password strength validation with six security criteria and real-time scoring that provides immediate visual feedback through a progress bar and color-coded strength indicator. The component uses useMemo for performance optimization, dynamically calculates password strength based on multiple criteria, and shows a detailed checklist to guide users toward creating secure passwords. The validation provides progressive feedback without overwhelming users initially.

Best Practice Note:

This is the password validation pattern we use in CoreUI authentication components for enterprise-grade security requirements. Consider implementing additional checks like common password detection and provide password generation suggestions for optimal user security.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author