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

@blazefw/a11y

v0.1.1

Published

Blazefw Accessibility — runtime utilities, axe-core test helpers, and nexus-a11y compliance CLI

Readme

@blazefw/a11y

BlazeFW Accessibility — runtime utilities for focus management, screen reader announcements, skip navigation, and motion preferences. Includes @blazefw/a11y/test with axe-core helpers for Jest, and the nexus-a11y CLI for WCAG 2.1 AA compliance reporting.

Installation

npm install @blazefw/a11y
# peer dependencies
npm install react react-dom

Runtime utilities

useFocusTrap(ref, options?)

Traps keyboard focus inside a container — essential for modals, drawers, and dialogs. Restores focus to the previously-active element on unmount.

import { useRef } from 'react';
import { useFocusTrap } from '@blazefw/a11y';

function Modal({ isOpen, onClose, children }) {
  const ref = useRef<HTMLDivElement>(null);

  useFocusTrap(ref, {
    enabled: isOpen,
    onEscape: onClose,   // called when user presses Escape
  });

  return (
    <div ref={ref} role="dialog" aria-modal="true">
      {children}
    </div>
  );
}

Tab and Shift+Tab cycle through all focusable elements inside the container. Elements with [disabled] or [inert] are excluded automatically.

useAnnouncer(options?)

Sends messages to a live ARIA region — screen readers read the message aloud without moving focus. Useful for async status updates, form validation, and notifications.

import { useAnnouncer } from '@blazefw/a11y';

function SaveButton() {
  const { announce } = useAnnouncer({ politeness: 'polite' }); // or 'assertive'

  async function handleSave() {
    await save();
    announce('Changes saved successfully');
  }

  return <button onClick={handleSave}>Save</button>;
}

The announcer injects a visually-hidden aria-live div directly into document.body (stable across re-renders). Repeating the same message still triggers a screen reader announcement.

SkipNavLink / SkipNavContent

Adds a "Skip to main content" link — required for WCAG 2.4.1. Visually hidden until focused, then appears at the top of the page.

import { SkipNavLink, SkipNavContent } from '@blazefw/a11y';

// In your layout header:
<header>
  <SkipNavLink />
  <nav>...</nav>
</header>

// At the start of your main content:
<main>
  <SkipNavContent />
  <h1>Page title</h1>
  ...
</main>

Custom label and target:

<SkipNavLink label="Skip to search results" contentId="results" />
<SkipNavContent id="results" />

useReducedMotion()

Returns true when the user has enabled "Reduce Motion" in their OS preferences. Use to disable or simplify animations.

import { useReducedMotion } from '@blazefw/a11y';

function AnimatedCard({ children }) {
  const reduced = useReducedMotion();

  return (
    <div style={{
      transition: reduced ? 'none' : 'transform 300ms ease',
      transform: reduced ? 'none' : isVisible ? 'translateY(0)' : 'translateY(20px)',
    }}>
      {children}
    </div>
  );
}

VisuallyHidden

Renders content that is invisible to sighted users but readable by screen readers. Better than display: none or visibility: hidden which hide from all users.

import { VisuallyHidden } from '@blazefw/a11y';

// Add context to icon-only buttons
<button onClick={onClose}>
  <CloseIcon aria-hidden />
  <VisuallyHidden>Close dialog</VisuallyHidden>
</button>

// Use any HTML element
<VisuallyHidden as="span">Loading results...</VisuallyHidden>

Test utilities — @blazefw/a11y/test

axe-core integration for Jest + jsdom. Drop-in helpers for accessibility audits in unit tests.

npm install -D @blazefw/a11y axe-core
import { renderWithA11y, expectNoViolations, runA11yAudit } from '@blazefw/a11y/test';

describe('LoginForm', () => {
  it('has no accessibility violations', async () => {
    const { container } = renderWithA11y(<LoginForm />);
    await expectNoViolations(container);
  });

  it('reports violations for debugging', async () => {
    const { container } = renderWithA11y(<BadComponent />);
    const violations = await runA11yAudit(container);
    console.log(formatViolations(violations));
  });
});

Exports:

import {
  runA11yAudit,         // runs axe-core, returns violations array
  expectNoViolations,   // throws jest assertion if violations found
  renderWithA11y,       // wraps @testing-library/react's render
  formatViolations,     // formats violations as human-readable string
} from '@blazefw/a11y/test';

nexus-a11y CLI

Audits an HTML file or URL for WCAG 2.1 AA compliance. Reports axe-core violations, a manual checklist for the ~40% of rules that cannot be automated, and a WCAG coverage table.

Usage

# Audit an HTML file
npx nexus-a11y audit --file ./dist/index.html

# Audit a URL (requires a running server)
npx nexus-a11y audit --url http://localhost:3000

# Output formats
npx nexus-a11y audit --file index.html --format json
npx nexus-a11y audit --file index.html --format table   # default

Example output

VIOLATIONS (3 found, sorted by impact)
────────────────────────────────────────
[critical] image-alt       — <img> elements must have alt text          (2 elements)
[serious]  label           — Form elements must have labels              (1 element)
[moderate] color-contrast  — Elements must meet contrast ratio threshold (4 elements)

MANUAL CHECKLIST (20 items)
────────────────────────────────────────
□ 1.2.2  Captions (Prerecorded)   — Check all videos have accurate captions
□ 1.3.3  Sensory Characteristics  — Instructions don't rely on shape/colour alone
...

WCAG 2.1 AA COVERAGE
────────────────────────────────────────
Principle 1 (Perceivable)   ████████░░  8/10 automated
Principle 2 (Operable)      ██████░░░░  6/10 automated
Principle 3 (Understandable)████░░░░░░  4/10 automated
Principle 4 (Robust)        ██████████  10/10 automated

SUMMARY: 3 violations, 44/50 WCAG criteria checked (automated)

Exit codes

| Code | Meaning | |---|---| | 0 | No violations found | | 1 | One or more violations found | | 2 | CLI usage error |