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

validation-enhancer

v1.0.3

Published

The easiest, most lightweight validation system.

Readme

<validation-enhancer>

The easiest, most lightweight validation system.

npm install validation-enhancer
yarn add validation-enhancer

Try the LIVE DEMO!

Enhance

Wrap any HTML form in <validation-enhancer> to enhance its validation.

<validation-enhancer> is a web component that brings native HTML validation to life - with the UX you want right out of the box

<validation-enhancer-zod> is the same thing, but zod validates the form

Easy to Use!

  • Literally just wrap a form in <validation-enhancer>
  • Or wrap a form in <validation-enhancer-zod> and pass your zod schema to setZodSchema()

Great UX!

  • Displays error messages next to each input
  • Shows errors on focus out and submit
  • Clears errors immediately when the user corrects their input
  • Works with screen readers out of the box
  • Focuses the first invalid field on submit, and scrolls to its label
  • Progressive enhancement as standard - in the event of an error browser html validation will still function

Customisable!

  • Adds .valid / .invalid CSS classes on inputs as the user interacts, you control the style
  • Custom error messages in HTML attributes
  • Completely customisable validation using setCustomValidity()
  • Validate custom elements too!

Step 1

Wrap <validation-enhancer> around your form

<validation-enhancer>
  <form>

    <label for="email">Email</label>
    <input type="email" id="email" required />

    <button type="submit">Submit</button>
  </form>
</validation-enhancer>

Step 2

Assign each input an error display element using the aria-errormessage attribute

<validation-enhancer>
  <form>

    <label for="email">Email</label>
    <input type="email" id="email" required aria-errormessage="email-error" />
    <div id="email-error"></div>
    
    <button type="submit">Submit</button>
  </form>
</validation-enhancer>

Step 3

Style .valid, .invalid, and the validation message.

.valid {
  border-color: green;
}

.invalid {
  border-color: red;
}

Done!

That's all it takes to enhance your form!

<validation-enhancer>
  <form>

    <label for="email">Email</label>
    <input type="email" id="email" aria-errormessage="email-error" required />
    <div id="email-error" style="color:red"></div>
    
    <button type="submit">Submit</button>
  </form>
</validation-enhancer>

<style>
.valid {
  border-color: green;
}

.invalid {
  border-color: red;
}
</style>

<script type="module" src="validation-enhancer.min.js"></script>

Zod integration

Use a Zod schema as the single source of truth for validation. The zod schema will override any HTML attributes.

<validation-enhancer-zod>
  <form>
    
    <label for="email">Email</label>
    <input type="email" name="email_field" required aria-errormessage="email-error" />
    <div id="email-error"></div>

    <button type="submit">Submit</button>
  </form>
</validation-enhancer-zod>

<script>
import { z } from "zod";

/* Define Zod Schema */
const schema = z.object({
  /* Reference inputs by name attribute */
  email_field: z.string()
    .min(1, "Email is required.")
    .email("Please enter a valid email address."),
});

/* Run when the script is loaded */
customElements.whenDefined("validation-enhancer-zod").then(() => {
  const validationEnhancerZod = document.querySelector("validation-enhancer-zod");
  validationEnhancerZod.setZodSchema(schema);
});
</script>

Inputs are matched to schema fields by their name attribute — inputs without a name are skipped by zod validation.

Use getZodSchema() to read back the current schema.

Install

npm install validation-enhancer
yarn add validation-enhancer

Import

import "validation-enhancer";
import "validation-enhancer-zod";

Or copy dist/validation-enhancer.min.js into your project and load it directly:

<script type="module" src="validation-enhancer.min.js"></script>
<script type="module" src="validation-enhancer-zod.min.js"></script>

Custom errors

<input
  type="email"
  id="email"
  required
  aria-errormessage="email-error"
  validation-valueMissing="An email address is required."
  validation-typeMismatch="That doesn't look like a valid email."
>

Override the browser's default validation text by adding attributes that match validity state keys. Both validation-* and data-validation-* forms are accepted.

Attributes are checked in the following order, to mimic default browser behaviour. Bare attributes are checked before data- attributes.

| Attribute | Triggered when | | -------------------------------- | ------------------------------------- | | validation-valueMissing | Required field is empty | | validation-typeMismatch | Value doesn't match type (eg email) | | validation-patternMismatch | Value doesn't match pattern | | validation-tooLong | Value exceeds maxlength | | validation-tooShort | Value is shorter than minlength | | validation-rangeUnderflow | Number is below min | | validation-rangeOverflow | Number is above max | | validation-stepMismatch | Number doesn't match step | | validation-badInput | Browser can't parse the input |

If no custom message is set, the browser's built-in validationMessage is used.

<validation-enhancer-zod> gets its error messages from the zod schema instead.

Custom message prefix

The default prefix is "validation". Change it with the message-prefix attribute to avoid conflicts or match your own naming convention:

<validation-enhancer message-prefix="custom">
  <form>
    <input
      required
      custom-valueMissing="Please fill this out."
      aria-errormessage="msg"
    >
    <!-- also accepts data-custom-valueMissing -->
    <div id="msg"></div>
  </form>
</validation-enhancer>

CSS classes

The component adds these classes to each validated input and also manages aria-invalid:

| Class / attribute | When | | --------------------- | -------------------------- | | .valid | Input passes validation | | .invalid | Input fails validation | | aria-invalid="true" | Input fails validation |

Style them however you like:

.valid {
  border-color: green;
}

.invalid {
  border-color: red;
}

Custom class names

By default the component uses .valid and .invalid. Override them with the valid-class and invalid-class attributes:

<validation-enhancer valid-class="ok" invalid-class="error">
  <form>
    <!-- inputs will receive ".ok" / ".error" when validating -->
  </form>
</validation-enhancer>
input.ok    { border-color: green; }
input.error { border-color: red; }

Custom aria-live urgency

By default the component sets aria-live="polite" on error message elements. Override it with message-aria-live:

<validation-enhancer message-aria-live="assertive">

Custom message target attribute

By default, the component locates each input's companion message element via aria-errormessage. If your markup uses a different attribute, set message-target-attr. For example, some older screenreaders might respond better to "aria-describedby" than the newer "aria-errormessage":

<validation-enhancer message-target-attr="aria-describedby">
  <form>
    <input required aria-describedby="email-error">
    <div id="email-error"></div>
  </form>
</validation-enhancer>

Inputs that lack the configured attribute fall back to the browser's native reportValidity().

Scroll behaviour

On submit, focuses the first invalid field and scrolls to its label. The scroll can be configured with attributes on <validation-enhancer>:

| Attribute | Effect | | -------------------- | ---------------------------------------------------------------------- | | scroll-behavior | ScrollBehavior string passed to scrollIntoView, default "smooth" | | scroll-block | block option for scrollIntoView | | scroll-inline | inline option for scrollIntoView | | scroll-align-to-top| When present, passes a boolean to scrollIntoView instead of options object ("false"false, anything else → true) | | scroll-container | CSS selector for a custom scroll container — scrolls that element instead of calling scrollIntoView |

Programmatic value changes

The component listens for change, focusout, and keyup events. If you set an input's value in JavaScript, dispatch a change event so validation picks it up:

input.value = "new value";
input.dispatchEvent(new Event("change", { bubbles: true }));

The web component registers newly-added forms and fields, if they are modified after instantiation.

Versions

dist/validation-enhancer.js: Unminified, for development

dist/validation-enhancer.min.js: Minified, for production

dist/validation-enhancer.compat.min.js: ES2017 build minified, for production - compatible with older browsers

dist/validation-enhancer-zod.js: Comes with main validation-enhancer included. Unminified, for development

dist/validation-enhancer-zod.min.js: Comes with main validation-enhancer included. Minified, for production

dist/validation-enhancer-zod.compat.min.js: Comes with main validation-enhancer included. ES2017 build minified, for production - compatible with older browsers

Development

npm install        # install dependencies
npm run build      # compile to dist/
npm run demo       # open demo page
npm test           # run tests (vitest)
npm run test:e2e   # run tests (playwright)
npm run lint       # eslint
npm run format     # prettier --write