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

alpidate

v3.0.6

Published

A model-based validation plugin for Alpine.js, inspired by Vuelidate.

Readme

alpidate

A lightweight validation plugin for Alpine.js inspired by Vuelidate.

npm

Alpidate on npm

Demo

Try the live demo here: Alpidate Live Demo

Installation

Via npm (Recommended for Module Bundlers)

You can install alpidate via npm:

npm install alpidate

Then import and register:

import Alpine from 'alpinejs';
import alpidate from 'alpidate';
Alpine.plugin(alpidate);
Alpine.start();

Via CDN (For Quick Prototyping or Static Sites)

You can load alpidate directly from a CDN like unpkg:

<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/alpidate/dist/alpidate.cdn.js"></script>
<script>
  document.addEventListener('alpine:init', () => {
    Alpine.plugin(alpidate)
  })
</script>

Note: Ensure Alpine.js is loaded before alpidate. This uses the global alpidate export.

Usage

Setting Up Validation in a Component

Define validation rules inside the validations property and initialize validation in init():

Alpine.data('app', () => ({
  init() {
    // default: validation state stored on $v
    this.$validation(this); // -> creates this.$v
  }
  // Validation rules
  validations: {
    'first_name': ['required', 'min:3'],
    'last_name': ['required', 'min:3'],
    'delivery_note': ['requiredIf:express_delivery,true', 'max:100'],
    'email': ['required', 'email'],
    'address': ['required', 'array'],
    'address.*.name': ['required', 'min:2'],
    'address.*.address': ['required', 'min:5'],
    'address.*.phone': ['regex:^\\d{10}$']
  },
  // Form data
  first_name: '',
  last_name: '',
  email: '',
  express_delivery: false,
  delivery_note : '',
  address: [
    { name: '', address: '', phone: '' },
    { name: '', address: '', phone: '' }
  ]
}));

Nested components / isolated validation state

If you use nested x-data components and need each component to keep its own validation state (instead of sharing the default $v), pass a custom key when initializing. This creates a separate validation tree under that key and prevents collisions/overwrites with parent components. All validation-related properties (e.g., state, $invalid, $touch, validate()) will be stored under the custom key, not the default $v:

// inside a nested component's init()
this.$validation(this, '$v2'); // -> creates this.$v2 (isolated)

Supported Validation Rules

| Rule | Description | |------------|--------------------------------------------------------------------------- | | required | Ensures the field is not empty. | | requiredIf | Ensures the field is required only if a specified condition is met, based on the value of another field. The condition is defined as requiredIf:field,expectedValue, where the field must match the expected value for the validation to apply. | | numeric | The field must contain only numbers. | | email | Validates an email format. | | regex | Allows custom validation rules using regular expressions. | | min:value | Specifies the minimum length or value. | | max:value | Specifies the maximum length or value. | | array | Ensures the field is an array. |

Nested models and array items are supported, for example:

// Nested model
'form.firstName': ['required', 'min:3']

// Array item validation using wildcard '*'
'address.*.name': ['required', 'min:2']
'address.*.phone': ['regex:^\\d{10}$']

Accessing Validation State

All validation state is stored under the specified key (defaults to $v). Each model inside the validation state contains:

  • Rule results: e.g., required, min, regex, etc. Each key shows whether that specific rule passed (false) or failed (true).
  • $invalid: Boolean indicating if any of the assigned rules failed for that model.

For array fields, use each to access per-item validation:

// Access validation for first item in the address array
this.$v.address.each[0].name.$invalid // true or false
this.$v.address.each[1].phone.regex   // true or false

Special properties :

  • $v.$touch – Controls when validation messages appear. It remains false until you manually trigger validation with :
this.$v.validate();
  • $v.$invalid – Boolean indicating whether any rule in the entire form fails. Whenever a model changes, its validation state updates automatically. Use $touch to delay showing errors until, for example, form submission.

For isolated / nested components:

If you initialized validation with a custom key (e.g., this.$validation(this, '$v2')), the validation tree and special props live under that key:

// init inside nested component
this.$validation(this, '$v2'); // creates this.$v2

// run full validation
this.$v2.validate();

// or validate a single model
this.$v2.validate('selectedAddress');

Displaying Validation Errors in Template

Use the validation key to conditionally display validation errors in your template:

<span x-show="$v.first_name.$invalid && $v.$touch">
    <small x-show="$v.first_name.required" class="text-red">First Name is required</small>
    <small x-show="!$v.first_name.required && $v.first_name.min" class="text-red">Minimum 3 characters</small>
</span>

<template x-for="(addr, idx) in address" :key="idx">
  <div>
    <input x-model="addr.name" placeholder="Name">
    <span x-show="$v.address.each[idx].name.$invalid && $v.$touch">
        <small x-show="$v.address.each[idx].name.required" class="text-red">Address is required</small>
        <small x-show="!$v.address.each[idx].name.required && $v.address.each[idx].name.min" class="text-red">Minimum 2 characters</small>
    </span>
  </div>
</template>

For custom keys (e.g., $v2), replace $v with $v2 in the template:

<span x-show="$v2.first_name.$invalid && $v2.$touch">...</span>

Understanding the Validation State

  • Each model inside the validation state has an $invalid property indicating if all assigned validation rules pass.
  • $touch helps control when validation messages appear (e.g., after form submission).
  • Array items are available via arrayField.each under the validation key.

License

MIT License