npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

auto-form-guard

v1.5.1

Published

**Automated form validation for React and Angular applications with zero boilerplate code.**

Readme

🔒 Auto Form Guard

Automated form validation for React and Angular applications with zero boilerplate code.

Auto Form Guard is a powerful, zero-configuration form validation library that automatically detects and validates form fields based on their names. No need to write validation logic, error handling, or state management - it's all handled automatically!

✨ Features

  • 🎯 Zero Configuration - Automatically detects field types (email, phone, password) from field names
  • 🚀 Real-time Validation - Instant feedback as users type with debounced validation
  • 🔐 Password Strength Indicator - Visual password strength feedback with color-coded progress bars
  • Smart Error Messages - Context-aware error messages that appear when fields are touched
  • 🎨 Auto-styled Errors - Automatic error styling with red borders and error icons
  • 📦 Multiple Presets - BASIC, STANDARD, and STRICT validation presets
  • 🔧 Fully Customizable - Override any validation rule with custom configuration
  • 🎭 Confirm Password - Automatic confirm password validation (no code needed!)
  • 📅 Date Field Validation - Automatic DOB and booking date validation with age restrictions
  • 📱 Framework Agnostic Core - Use validation logic in any JavaScript/TypeScript project
  • ⚛️ React & Angular Support - Works seamlessly with both React and Angular

📦 Installation

npm install auto-form-guard

🚀 Quick Start

Basic Usage

import { AutoForm } from "auto-form-guard";

function MyForm() {
  return (
    <AutoForm
      onSubmit={(data) => {
        console.log("Validated data:", data);
        // Submit to your API
      }}
    >
      <input name="email" type="email" placeholder="Email" />
      <input name="phone" type="tel" placeholder="Phone" />
      <input name="password" type="password" placeholder="Password" />
      <input name="confirmPassword" type="password" placeholder="Confirm Password" />
      <button type="submit">Submit</button>
    </AutoForm>
  );
}

That's it! The form automatically validates:

  • ✅ Email format
  • ✅ Phone number (10 digits)
  • ✅ Password strength (STANDARD preset)
  • ✅ Confirm password matching

Angular Usage

Note: The Angular directive is available in the package. You can copy the auto-form.directive.ts from the test folder or use the validation functions directly.

import { Component } from '@angular/core';
import { AutoFormDirective } from './auto-form.directive'; // Copy from test folder or create your own

@Component({
  selector: 'app-my-form',
  template: `
    <form autoForm [config]="'STANDARD'" (formSubmit)="onSubmit($event)">
      <input name="email" type="email" placeholder="Email" required />
      <input name="phone" type="tel" placeholder="Phone" />
      <input name="password" type="password" placeholder="Password" required />
      <input name="confirmPassword" type="password" placeholder="Confirm Password" required />
      <button type="submit">Submit</button>
    </form>
  `,
  standalone: false
})
export class MyFormComponent {
  onSubmit(data: Record<string, any>) {
    console.log('Validated data:', data);
    // Submit to your API
  }
}

For Angular modules:

import { NgModule } from '@angular/core';
import { AutoFormDirective } from './auto-form.directive';

@NgModule({
  declarations: [MyFormComponent, AutoFormDirective],
  // ...
})
export class MyFormModule {}

That's it! The directive automatically validates:

  • ✅ Email format
  • ✅ Phone number (10 digits)
  • ✅ Password strength (STANDARD preset)
  • ✅ Confirm password matching
  • ✅ Real-time validation with error display
  • ✅ Password strength indicator

📊 Code Reduction Comparison

❌ Without Auto Form Guard (Traditional Approach)

import { useState } from "react";

function MyForm() {
  const [email, setEmail] = useState("");
  const [phone, setPhone] = useState("");
  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [errors, setErrors] = useState({});
  const [touched, setTouched] = useState({});
  const [passwordStrength, setPasswordStrength] = useState(null);

  // Email validation
  const validateEmail = (email) => {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
  };

  // Phone validation
  const validatePhone = (phone) => {
    return /^[0-9]{10}$/.test(phone);
  };

  // Password validation
  const validatePassword = (password) => {
    if (password.length < 8) return false;
    if (!/[A-Z]/.test(password)) return false;
    if (!/[a-z]/.test(password)) return false;
    if (!/[0-9]/.test(password)) return false;
    if (!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)) return false;
    return true;
  };

  // Password strength calculation
  const calculateStrength = (password) => {
    let score = 0;
    if (password.length >= 8) score++;
    if (/[A-Z]/.test(password)) score++;
    if (/[a-z]/.test(password)) score++;
    if (/[0-9]/.test(password)) score++;
    if (/[^A-Za-z0-9]/.test(password)) score++;
    return score;
  };

  // Handle field changes
  const handleChange = (field, value) => {
    // Update state
    if (field === "email") setEmail(value);
    if (field === "phone") setPhone(value);
    if (field === "password") setPassword(value);
    if (field === "confirmPassword") setConfirmPassword(value);

    // Mark as touched
    setTouched(prev => ({ ...prev, [field]: true }));

    // Validate with debounce
    clearTimeout(window[`${field}Timer`]);
    window[`${field}Timer`] = setTimeout(() => {
      const newErrors = { ...errors };
      
      if (field === "email" && !validateEmail(value)) {
        newErrors.email = "Invalid email address";
      } else if (field === "phone" && !validatePhone(value)) {
        newErrors.phone = "Invalid phone number";
      } else if (field === "password") {
        if (!validatePassword(value)) {
          newErrors.password = "Invalid password";
        }
        setPasswordStrength(calculateStrength(value));
      } else if (field === "confirmPassword") {
        if (value !== password) {
          newErrors.confirmPassword = "Passwords do not match";
        }
      }
      
      setErrors(newErrors);
    }, 500);
  };

  // Handle submit
  const handleSubmit = (e) => {
    e.preventDefault();
    
    // Validate all fields
    const newErrors = {};
    if (!validateEmail(email)) newErrors.email = "Invalid email address";
    if (!validatePhone(phone)) newErrors.phone = "Invalid phone number";
    if (!validatePassword(password)) newErrors.password = "Invalid password";
    if (confirmPassword !== password) {
      newErrors.confirmPassword = "Passwords do not match";
    }
    
    if (Object.keys(newErrors).length > 0) {
      setErrors(newErrors);
      return;
    }
    
    // Submit data
    console.log({ email, phone, password });
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <input
          name="email"
          value={email}
          onChange={(e) => handleChange("email", e.target.value)}
          onBlur={() => setTouched(prev => ({ ...prev, email: true }))}
          style={{
            borderColor: errors.email && touched.email ? "red" : "gray"
          }}
        />
        {errors.email && touched.email && (
          <div style={{ color: "red" }}>❌ {errors.email}</div>
        )}
      </div>
      
      <div>
        <input
          name="phone"
          value={phone}
          onChange={(e) => handleChange("phone", e.target.value)}
          onBlur={() => setTouched(prev => ({ ...prev, phone: true }))}
          style={{
            borderColor: errors.phone && touched.phone ? "red" : "gray"
          }}
        />
        {errors.phone && touched.phone && (
          <div style={{ color: "red" }}>❌ {errors.phone}</div>
        )}
      </div>
      
      <div>
        <input
          name="password"
          type="password"
          value={password}
          onChange={(e) => handleChange("password", e.target.value)}
          onBlur={() => setTouched(prev => ({ ...prev, password: true }))}
          style={{
            borderColor: errors.password && touched.password ? "red" : "gray"
          }}
        />
        {errors.password && touched.password && (
          <div style={{ color: "red" }}>❌ {errors.password}</div>
        )}
        {passwordStrength && (
          <div>
            <div style={{
              width: `${passwordStrength * 20}%`,
              height: "4px",
              backgroundColor: passwordStrength >= 4 ? "green" : "orange"
            }} />
            Strength: {passwordStrength >= 4 ? "Strong" : "Weak"}
          </div>
        )}
      </div>
      
      <div>
        <input
          name="confirmPassword"
          type="password"
          value={confirmPassword}
          onChange={(e) => handleChange("confirmPassword", e.target.value)}
          onBlur={() => setTouched(prev => ({ ...prev, confirmPassword: true }))}
          style={{
            borderColor: errors.confirmPassword && touched.confirmPassword ? "red" : "gray"
          }}
        />
        {errors.confirmPassword && touched.confirmPassword && (
          <div style={{ color: "red" }}>❌ {errors.confirmPassword}</div>
        )}
      </div>
      
      <button type="submit">Submit</button>
    </form>
  );
}

Lines of Code: ~150+ lines
Complexity: High
Maintenance: Difficult

✅ With Auto Form Guard

import { AutoForm } from "auto-form-guard";

function MyForm() {
  return (
    <AutoForm
      onSubmit={(data) => {
        console.log("Validated data:", data);
        // Submit to your API
      }}
    >
      <input name="email" type="email" placeholder="Email" />
      <input name="phone" type="tel" placeholder="Phone" />
      <input name="password" type="password" placeholder="Password" />
      <input name="confirmPassword" type="password" placeholder="Confirm Password" />
      <button type="submit">Submit</button>
    </AutoForm>
  );
}

Lines of Code: ~15 lines
Complexity: Low
Maintenance: Easy

📈 Reduction Summary

  • 90% less code (150+ lines → 15 lines)
  • Zero validation logic to write
  • Zero error handling code
  • Zero state management for form fields
  • Automatic real-time validation
  • Automatic error styling
  • Automatic password strength indicator
  • Automatic confirm password matching

🎯 Configuration Presets

BASIC Preset

Minimal requirements for quick validation:

<AutoForm config="BASIC" onSubmit={handleSubmit}>
  <input name="email" type="email" />
  <input name="phone" type="tel" />
  <input name="password" type="password" />
  <button type="submit">Submit</button>
</AutoForm>

Requirements:

  • Email: Valid format
  • Phone: 10 digits
  • Password: 8+ chars, uppercase, number

STANDARD Preset (Default)

Balanced security and usability:

<AutoForm config="STANDARD" onSubmit={handleSubmit}>
  {/* Same fields */}
</AutoForm>

Requirements:

  • Email: Valid format
  • Phone: 10 digits
  • Password: 8+ chars, uppercase, lowercase, number, special char

STRICT Preset

Maximum security requirements:

<AutoForm config="STRICT" onSubmit={handleSubmit}>
  {/* Same fields */}
</AutoForm>

Requirements:

  • Email: Valid format
  • Phone: 10 digits
  • Password: 12+ chars, all requirements, no repeating/sequential chars

🔧 Custom Configuration

Override any validation rule:

<AutoForm
  config={{
    realTimeValidation: true,
    email: {
      enabled: true,
      blockDisposable: false,
    },
    phone: {
      enabled: true,
      format: '10-digit',
    },
    password: {
      enabled: true,
      minLength: 6,
      requireUppercase: false,
      requireLowercase: true,
      requireNumbers: true,
      requireSpecialChars: false,
      noRepeatingChars: true,
      maxRepeatingChars: 5, // Allow up to 5 consecutive repeats
    },
  }}
  onSubmit={handleSubmit}
>
  {/* Your form fields */}
</AutoForm>

🎨 Features in Detail

1. Automatic Field Detection

The library automatically detects field types from field names:

  • Fields with email in the name → Email validation
  • Fields with phone in the name → Phone validation
  • Fields with password in the name → Password validation
  • Fields with confirmPassword → Confirm password validation
  • Fields with dob, birthday, birth → Date of Birth validation (past date, 18+ age)
  • Fields with booking → Booking date validation (future date)
  • Fields with date → Generic date validation

React:

<input name="userEmail" />        // ✅ Detected as email
<input name="phoneNumber" />      // ✅ Detected as phone
<input name="userPassword" />     // ✅ Detected as password
<input name="confirmPassword" />  // ✅ Detected as confirm password
<input name="dob" type="date" />  // ✅ Detected as DOB (past, 18+)
<input name="bookingDate" type="date" /> // ✅ Detected as booking (future)

Angular:

<input name="userEmail" type="email" />        <!-- ✅ Detected as email -->
<input name="phoneNumber" type="tel" />       <!-- ✅ Detected as phone -->
<input name="userPassword" type="password" /> <!-- ✅ Detected as password -->
<input name="confirmPassword" type="password" /> <!-- ✅ Detected as confirm password -->
<input name="dob" type="date" />             <!-- ✅ Detected as DOB (past, 18+) -->
<input name="bookingDate" type="date" />     <!-- ✅ Detected as booking (future) -->

2. Real-time Validation

Validation happens automatically as users type (with 500ms debounce):

// No code needed! Just use AutoForm
<AutoForm onSubmit={handleSubmit}>
  <input name="email" type="email" />
  {/* Errors appear automatically when field is touched */}
</AutoForm>

3. Password Strength Indicator

Visual feedback for password strength:

  • Very Weak (Red) - Score: 0-20%
  • Weak (Orange) - Score: 21-40%
  • Medium (Yellow) - Score: 41-60%
  • Strong (Light Green) - Score: 61-80%
  • Very Strong (Green) - Score: 81-100%

Automatically displayed below password fields with a progress bar and feedback message.

4. Confirm Password Validation

Zero code required! Just name your field confirmPassword:

<AutoForm onSubmit={handleSubmit}>
  <input name="password" type="password" />
  <input name="confirmPassword" type="password" />
  {/* Automatically validates that passwords match */}
</AutoForm>

The library automatically:

  • ✅ Requires confirm password when password is set
  • ✅ Validates that passwords match
  • ✅ Shows "Passwords do not match" error
  • ✅ Clears error when passwords match

5. Smart Error Display

Errors only appear when:

  • Field has been touched (user interacted with it)
  • Field has a value
  • Validation fails

This prevents overwhelming users with errors before they've finished typing.

6. Date Field Validation

Automatic DOB Validation: Fields with names containing dob, birthday, or birth are automatically configured to:

  • Must be in the past (cannot be today or future)
  • Must be 18+ years old (default)
  • Required (if marked as required)

React Example:

<AutoForm onSubmit={handleSubmit}>
  <input name="dob" type="date" required />
  {/* Automatically validates: past date, 18+ age */}
</AutoForm>

Angular Example:

<form autoForm [config]="'STANDARD'" (formSubmit)="onSubmit($event)">
  <input name="dob" type="date" required />
  <!-- Automatically validates: past date, 18+ age -->
</form>

Automatic Booking Date Validation: Fields with names containing booking are automatically configured to:

  • Must be in the future (cannot be today or past)
  • Required (if marked as required)

React Example:

<AutoForm onSubmit={handleSubmit}>
  <input name="bookingDate" type="date" required />
  {/* Automatically validates: future date */}
</AutoForm>

Angular Example:

<form autoForm [config]="'STANDARD'" (formSubmit)="onSubmit($event)">
  <input name="bookingDate" type="date" required />
  <!-- Automatically validates: future date -->
</form>

Both in One Form:

<AutoForm onSubmit={handleSubmit} config="STANDARD">
  <input name="dob" type="date" required />
  <input name="bookingDate" type="date" required />
  <button type="submit">Submit</button>
</AutoForm>

The library automatically handles both date types in the same form without any configuration!

📚 API Reference

AutoForm Component (React)

<AutoForm
  onSubmit={(data: Record<string, any>) => void}
  config?: 'BASIC' | 'STANDARD' | 'STRICT' | ValidationConfig
>
  {/* Your form fields */}
</AutoForm>

Props:

  • onSubmit: Callback function called when form is submitted with valid data
  • config: Validation preset or custom configuration object (optional, defaults to 'STANDARD')

AutoFormDirective (Angular)

<form 
  autoForm 
  [config]="'BASIC' | 'STANDARD' | 'STRICT' | ValidationConfig"
  (formSubmit)="onSubmit($event)">
  <!-- Your form fields -->
</form>

Inputs:

  • config: Validation preset or custom configuration object (optional, defaults to 'STANDARD')

Outputs:

  • formSubmit: Event emitted when form is submitted with valid data

Methods:

  • getErrors(): Returns current validation errors
  • isValid(): Returns whether the form is currently valid

Usage Example:

@Component({
  template: `
    <form 
      autoForm 
      [config]="'STANDARD'" 
      (formSubmit)="handleSubmit($event)"
      #formRef="autoForm">
      <input name="email" type="email" required />
      <input name="password" type="password" required />
      <button type="submit">Submit</button>
    </form>
  `
})
export class MyComponent {
  handleSubmit(data: Record<string, any>) {
    console.log('Validated data:', data);
  }
}

validateForm Function

Use the validation logic outside of React:

import { validateForm } from "auto-form-guard";

const result = validateForm(
  {
    email: "[email protected]",
    phone: "1234567890",
    password: "Test@123",
    confirmPassword: "Test@123"
  },
  "STANDARD"
);

console.log(result.valid); // true or false
console.log(result.errors); // { email: "...", password: "..." }

🌍 Environment Variables

Configure presets via environment variables:

VITE_AUTO_FORM_PRESET=STRICT

Or in your code:

const preset = import.meta.env.VITE_AUTO_FORM_PRESET || "STANDARD";
<AutoForm config={preset} onSubmit={handleSubmit}>
  {/* Your form */}
</AutoForm>

🧪 Testing

Run the password validation test suite:

cd testing
npm run test:password

This runs 18+ test cases covering all validation scenarios.

📅 Date Field Examples

Complete Form with Date Fields

React:

import { AutoForm } from "auto-form-guard";

function RegistrationForm() {
  return (
    <AutoForm onSubmit={(data) => console.log(data)} config="STANDARD">
      <input name="email" type="email" required />
      <input name="phone" type="tel" />
      <input name="password" type="password" required />
      <input name="confirmPassword" type="password" required />
      
      {/* DOB - Auto-validates as past date, 18+ */}
      <input name="dob" type="date" required />
      
      {/* Booking Date - Auto-validates as future date */}
      <input name="bookingDate" type="date" required />
      
      <button type="submit">Submit</button>
    </AutoForm>
  );
}

Angular:

<form autoForm [config]="'STANDARD'" (formSubmit)="onSubmit($event)">
  <input name="email" type="email" required />
  <input name="phone" type="tel" />
  <input name="password" type="password" required />
  <input name="confirmPassword" type="password" required />
  
  <!-- DOB - Auto-validates as past date, 18+ -->
  <input name="dob" type="date" required />
  
  <!-- Booking Date - Auto-validates as future date -->
  <input name="bookingDate" type="date" required />
  
  <button type="submit">Submit</button>
</form>

Custom Date Configuration

React:

import { AutoForm } from "auto-form-guard";
import type { ValidationConfig } from "auto-form-guard";

const customConfig: ValidationConfig = {
  date: {
    required: true,
    mustBePast: true,      // For DOB
    minAge: 18,            // Minimum age
    maxAge: 100,           // Maximum age
    minDate: "1900-01-01", // Minimum date
    maxDate: "2010-12-31"  // Maximum date
  }
};

<AutoForm config={customConfig} onSubmit={handleSubmit}>
  <input name="birthDate" type="date" required />
</AutoForm>

Angular:

import { ValidationConfig } from 'auto-form-guard';

export class MyComponent {
  customConfig: ValidationConfig = {
    date: {
      required: true,
      mustBePast: true,
      minAge: 18,
      maxAge: 100,
      minDate: "1900-01-01",
      maxDate: "2010-12-31"
    }
  };
}
<form autoForm [config]="customConfig" (formSubmit)="onSubmit($event)">
  <input name="birthDate" type="date" required />
</form>

🎯 Use Cases

Perfect For:

  • ✅ Registration forms
  • ✅ Login forms
  • ✅ Password reset forms
  • ✅ Profile update forms
  • ✅ Settings forms
  • ✅ Booking/Appointment forms
  • ✅ Any form with email/phone/password/date fields

Benefits:

  • 🚀 Faster Development - Write forms in minutes, not hours
  • 🐛 Fewer Bugs - Battle-tested validation logic
  • 📱 Better UX - Real-time feedback and clear error messages
  • 🔒 Secure by Default - Strong password requirements out of the box
  • 🎨 Consistent UI - Uniform error styling across your app

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

MIT License - feel free to use in your projects!

🙏 Acknowledgments

Built with ❤️ for developers who want to focus on building features, not validation logic.


Made with Auto Form Guard - Because form validation shouldn't be a chore! 🚀