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

@pigmilcom/a11y

v1.2.9

Published

WCAG 2.1 accessibility widget for React — text size, contrast, dyslexia font, motion reduction, and more.

Readme

@pigmilcom/a11y

About Simple, lightweight accessibility widget that enhances usability and adds control features to any website instantly. Zero dependencies. WCAG 2.1 Ready. Drop in one <script> tag or install via npm — visitors get instant control over text size, contrast, colour filters, motion, and more. Preferences persist via localStorage.


CDN — Plug & Play

No React, no npm, no build step. Add one tag to your <head>.

jsDelivr (recommended)

Served from the npm registry via jsDelivr's global edge network — always the latest published version:

<script
  src="https://cdn.jsdelivr.net/npm/@pigmilcom/a11y/dist/a11y.cdn.js"
  data-position="bottom-right"
></script>

Pin to a specific version:

<script
  src="https://cdn.jsdelivr.net/npm/@pigmilcom/[email protected]/dist/a11y.cdn.js"
  data-position="bottom-right"
></script>

Self-hosted (pigmil CDN)

Use your own CDN endpoint for full control over deployment:

<script
  src="https://cdn.pigmil.com/a11y/dist/a11y.cdn.js"
  data-position="bottom-right"
></script>

The widget auto-mounts on DOMContentLoaded. React 18 and all CSS are bundled inside — nothing else needed.

data-position values

| Value | Placement | | --------------- | ------------------ | | bottom-right | Bottom-right corner (default) | | bottom-left | Bottom-left corner | | top-right | Top-right corner | | top-left | Top-left corner |

data-theme values

| Value | Behaviour | | -------- | ------------------------------------------------------ | | omitted / auto | Matches <html class="dark"> or color-scheme: dark; otherwise light | | light | Always use the light theme | | dark | Always use the dark theme |

data-lang values

| Value | Language | | ----- | -------- | | en | English (default) | | es | Spanish | | fr | French | | de | German | | pt | Portuguese | | zh | Chinese (Simplified) | | ar | Arabic | | hi | Hindi |

Language resolution works like this:

  1. If data-lang or the React lang prop is provided, that language is used and saved to localStorage['a11y-lang'].
  2. If data-lang / lang is omitted, the widget reads localStorage['a11y-lang'].
  3. If localStorage['a11y-lang'] does not exist yet, the widget defaults to 'en' and saves it.

This means the widget language can be changed dynamically by updating localStorage['a11y-lang'].

<!-- Default — follows the page's html theme, reads a11y-lang from localStorage, falls back to en -->
<script
  src="https://cdn.jsdelivr.net/npm/@pigmilcom/a11y/dist/a11y.cdn.js"
  data-position="bottom-right"
></script>

<!-- Equivalent explicit auto mode -->
<script
  src="https://cdn.jsdelivr.net/npm/@pigmilcom/a11y/dist/a11y.cdn.js"
  data-position="bottom-right"
  data-theme="auto"
></script>

<!-- Force light theme -->
<script
  src="https://cdn.jsdelivr.net/npm/@pigmilcom/a11y/dist/a11y.cdn.js"
  data-position="bottom-right"
  data-theme="light"
></script>

<!-- Force dark theme -->
<script
  src="https://cdn.jsdelivr.net/npm/@pigmilcom/a11y/dist/a11y.cdn.js"
  data-position="bottom-right"
  data-theme="dark"
></script>

<!-- Spanish UI -->
<script
  src="https://cdn.jsdelivr.net/npm/@pigmilcom/a11y/dist/a11y.cdn.js"
  data-position="bottom-right"
  data-lang="es"
></script>
localStorage.setItem('a11y-lang', 'fr');
window.dispatchEvent(new CustomEvent('pgm-a11y-language-change', {
  detail: { lang: 'fr' }
}));

If you still pass data-lang="fr", that explicit value wins and also updates localStorage['a11y-lang'].

Programmatic control

The CDN build exposes window.PigmilA11y for manual control:

PigmilA11y.mount();    // mount the widget
PigmilA11y.unmount();  // remove the widget and clean up

npm Installation

npm install @pigmilcom/a11y
# yarn
yarn add @pigmilcom/a11y
# pnpm
pnpm add @pigmilcom/a11y

Features

  • Text size — Normal / Large / X-Large
  • High contrast
  • Invert colours
  • Grayscale
  • Reduce motion
  • Highlight links
  • Text spacing (WCAG 1.4.12)
  • Dyslexia-friendly font
  • Persists in localStorage
  • Full keyboard & screen-reader support (role="dialog", aria-checked, aria-expanded)
  • Zero runtime dependencies (React peer dep only)

Dist files

Every build outputs these files to dist/:

| File | Format | Description | | ------------------- | ------ | --------------------------------------------- | | index.js | CJS | npm (unminified, for bundlers) | | index.mjs | ESM | npm (unminified, for bundlers) | | index.min.js | CJS | npm (minified) | | index.min.mjs | ESM | npm (minified) | | index.css | CSS | Stylesheet import (@pigmilcom/a11y/styles) | | index.min.css | CSS | Minified stylesheet | | a11y.cdn.js | IIFE | CDN bundle — React bundled, CSS inlined, minified |


Quick start (React)

1 — Import the stylesheet (once, globally)

import '@pigmilcom/a11y/styles';

This single import contains both the panel UI styles and all the accessibility class rules applied to <html>.

2 — Drop in the widget

import a11y from '@pigmilcom/a11y';

// Assign to a capitalized variable to use in JSX
const A11y = a11y;

<A11y className="fixed bottom-4 right-4 rounded" />

The className prop is merged onto the trigger button — use Tailwind classes, custom classes, or anything your bundler supports to position the widget. The lang prop is reactive, and when provided it also syncs localStorage['a11y-lang'].


Customising the widget with CSS

The widget exposes stable a11y-widget-* class names on its key elements as a public API. Target them from a <style> tag (CDN / self-hosted) or your own stylesheet (React):

<style>
  /* Trigger button */
  .a11y-widget-btn {
    border-radius: 8px !important;
    background: rgba(15, 15, 40, 0.9) !important;
  }

  /* Dialog panel */
  .a11y-widget-dialog {
    border-color: rgba(99, 102, 241, 0.4) !important;
  }

  /* Toggle option rows */
  .a11y-widget-toggle-btn:hover {
    background: rgba(99, 102, 241, 0.06) !important;
  }
</style>

| Public class | Element | | --------------------------- | -------------------- | | a11y-widget-btn | Trigger button | | a11y-widget-dialog | Dialog panel | | a11y-widget-toggle-btn | Each toggle option |

Place your <style> tag after the widget <script> tag so it takes precedence in the cascade. Use !important where the widget's base styles have higher specificity.


Tailwind CSS support

Tailwind utility classes work transparently via the className prop:

import a11y from '@pigmilcom/a11y';
const A11y = a11y;

// Tailwind classes are passed straight through to the trigger button
<A11y className="fixed bottom-6 right-6 rounded-full shadow-xl" lang="de" />

Because the classes come from your source files, Tailwind's JIT scanner picks them up automatically. No purge exceptions or safelist entries needed.


Framework examples

Next.js App Router

// app/layout.jsx
import '@pigmilcom/a11y/styles';
import a11y from '@pigmilcom/a11y';

const A11y = a11y;

export default function RootLayout({ children }) {
    return (
        <html lang="en">
            <body>
                {children}
                <A11y className="fixed bottom-4 right-4 rounded" lang="en" />
            </body>
        </html>
    );
}

The component is already marked 'use client' — no extra wrapper needed.

Vite + React

// src/App.jsx
import a11y from '@pigmilcom/a11y';

const A11y = a11y;

export default function App() {
    return (
        <>
            {/* …your content… */}
            <A11y className="fixed bottom-4 right-4 rounded" lang="pt" />
        </>
    );
}

Props

| Prop | Type | Default | Description | | ----------- | -------- | -------- | ---------------------------------------------------- | | className | string | — | Extra classes added to the trigger <button> | | theme | string | inferred | Widget colour theme: 'auto' | 'light' | 'dark' | | lang | string | localStorage['a11y-lang'] or 'en' | Widget UI language: 'en', 'es', 'fr', 'de', 'pt', 'zh', 'ar', 'hi' |

theme prop

| Value | Behaviour | | -------- | ---------------------------------------------------------------- | | omitted / 'auto' | Matches <html class="dark"> or color-scheme: dark; otherwise light | | 'light'| Always renders the light theme | | 'dark' | Always renders the dark theme |

import a11y from '@pigmilcom/a11y';
const A11y = a11y;

// Follow the page's html theme (default)
<A11y className="fixed bottom-4 right-4" />

// Equivalent explicit auto mode
<A11y className="fixed bottom-4 right-4" theme="auto" />

// Always light
<A11y className="fixed bottom-4 right-4" theme="light" />

// Always dark
<A11y className="fixed bottom-4 right-4" theme="dark" />

// Change the widget UI language
<A11y className="fixed bottom-4 right-4" lang="zh" />
localStorage.setItem('a11y-lang', 'ar');
window.dispatchEvent(new CustomEvent('pgm-a11y-language-change', {
  detail: { lang: 'ar' }
}));

CSS classes applied to <html>

When a preference is enabled the widget adds a class to document.documentElement. All rules live in @pigmilcom/a11y/styles and can be freely overridden in your own stylesheet.

| Class | Feature | | ----------------------- | ----------------------------------------- | | a11y-text-lg | Font size +18 % | | a11y-text-xl | Font size +45 % | | a11y-high-contrast | Contrast filter (1.6×) | | a11y-invert | Invert colours (re-inverts images/video) | | a11y-grayscale | Grayscale filter | | a11y-reduce-motion | Strips all animations & transitions | | a11y-highlight-links | Outlines every link and [role="link"] | | a11y-text-spacing | Letter / word / line spacing (WCAG 1.4.12)| | a11y-dyslexia | Switches to a high-readability system font|


Storage

Preferences are saved under the localStorage key pgm-a11y as a JSON object. The widget reads and re-applies them on first client render, so preferences survive page reloads and navigation. On SSR the widget hydrates without errors — all DOM access is guarded by a mounted flag.

Widget language is stored separately under localStorage['a11y-lang'].

  • If data-lang or lang is provided, that value is normalized and saved to a11y-lang.
  • If no explicit language is provided, the widget reads a11y-lang.
  • If a11y-lang is missing, the widget sets it to 'en' automatically.
  • Updating a11y-lang and dispatching pgm-a11y-language-change updates the widget language dynamically on the same page.

Requirements

CDN

No dependencies. Works in any HTML page.

npm package

| Peer dependency | Version | | --------------- | ------- | | react | ≥ 17 | | react-dom | ≥ 17 |


License

MIT © pigmilcom

Free Usage

The free version is available for any domain and includes:

  • Up to 1,000 requests / day per domain
  • Up to 30,000 requests / month per domain

Full version (white-label)

The full version removes all limits and PIGMIL branding and can be fully white-labeled for your product.

For inquiries contact PIGMIL: