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 🙏

© 2025 – Pkg Stats / Ryan Hefner

a11y-inspector

v0.2.3

Published

Runtime accessibility auditing toolkit for modern SPAs and web apps.

Downloads

556

Readme

@example/dom-a11y-audit

Runtime accessibility auditing toolkit for modern single-page applications. Designed for reliability, low overhead, and privacy-first workflows.

Features

  • Live DOM scanner with MutationObserver-based incremental rescans, SPA route awareness, and Shadow DOM/iframe traversal
  • Production-ready rule set covering alt text, landmark/structure, focus management, keyboard traps, color contrast, forms, and cross-origin iframe reporting
  • Multiple reporters: structured JSON, console groups, SARIF, and optional in-page overlay with issue markers
  • Drop-in inspector button with live issue count and overlay toggle
  • Strong privacy guardrails: telemetry opt-in with hashed payloads, context masking, and zero default network egress
  • Extensible architecture for custom rules, formatters, and per-route configuration
  • Type-safe API surface with comprehensive TypeScript declarations
  • CI-friendly CLI (Node + JSDOM) with exit codes that fail builds on critical issues

Installation

npm install @example/dom-a11y-audit
# or
pnpm add @example/dom-a11y-audit

Quick Start

import { initAccessibilityPlugin } from '@example/dom-a11y-audit';

const controller = initAccessibilityPlugin(document, {
  overlay: true,
  outputFormat: 'console',
  performanceMode: 'balanced',
});

// Optional: subscribe to updates
const unsubscribe = controller.onUpdate((results) => {
  console.log('a11y issues', results);
});

Drop-in Inspector Button

Need a quick way to wire the overlay into your app? The library ships a ready-to-use floating button that tracks the live issue count and toggles the overlay:

import { initAccessibilityPlugin, attachInspectorButton } from 'a11y-inspector';

const controller = initAccessibilityPlugin(document, { overlay: false });
attachInspectorButton(controller, {
  position: 'bottom-left',
});

The button displays a real-time issue badge, triggers a fresh scan on click, and respects INSPECTOR_IGNORE_ATTRIBUTE so it never flags itself.

Configuration

| Option | Type | Default | Description | | --- | --- | --- | --- | | rules | string[] | all core rules | Whitelist of rule IDs to run | | disableRules | string[] | [] | Rule IDs to disable | | scanInterval | number | 250 | Debounce interval (ms) for incremental rescans | | performanceMode | 'aggressive' \| 'balanced' \| 'light' | 'balanced' | Workload tuning preset | | overlay | boolean | false | Enable in-page overlay with markers | | outputFormat | 'json' \| 'console' \| 'html' \| 'sarif' | 'console' | Reporter to emit after scans | | maskTextContent | boolean | false | Replace text nodes in context snippets with *** | | telemetry | {enabled:boolean, endpoint?:string, apiKey?:string} | telemetry disabled | Opt-in remote reporting with hashed payloads | | severityOverrides | {[ruleId]: 'critical'\|'major'\|'minor'\|'info'} | undefined | Adjust severity per rule | | ignoreSelectors | string[] | [] | Additional selectors to skip from scans (overlay UI is ignored by default) | | ignoreAttribute | string | 'data-a11y-inspector-ignore' | Attribute that marks DOM subtrees to ignore | | whitelistSelectors | string[] | [] | Alias for ignoreSelectors (supported for backward compatibility) |

Overlay Preview

When enabled, the overlay renders a floating panel listing issues. Each issue receives a numbered badge positioned near the offending node. Clicking a badge scrolls to the element, keeps focus, and displays patch guidance.

To prevent the inspector controls from self-reporting, add the data-a11y-inspector-ignore attribute (or your configured ignoreAttribute) to the container that renders the plugin UI.

Framework Integrations

Call controller.createAdapters() to obtain lightweight helpers:

  • React: Wrap your tree with the provider:

    1. const { createReactProvider } = controller.createAdapters();
    2. const AccessibilityProvider = createReactProvider(React);
    3. Render <AccessibilityProvider>{children}</AccessibilityProvider> once near the app root.
  • Vue 3 composition API:

    1. const { createVuePlugin } = controller.createAdapters();
    2. app.use(createVuePlugin({ onMounted, onBeforeUnmount }));
    3. The plugin will trigger scans on mount and cleanup on teardown.
  • Angular / Router Hooks: Invoke controller.scan() inside router events (e.g., router.events.subscribe). The DOM-driven scanner makes the integration trivial—no component instrumentation required.

  • Plain JS: Call initAccessibilityPlugin(document) during bootstrap. The MutationObserver keeps scans up-to-date as you mutate the DOM.

CLI Usage

# scan a static HTML export
npx @example/dom-a11y-audit cli --file dist/index.html --mask --format json

Exit status codes:

  • 0: no issues or only informational
  • 2: at least one critical issue detected (CI-friendly)

Reporting Formats

  • Console: Severity-grouped collapsible logs with color-coded suggestions.
  • JSON: Structured payload matching the ScanResult schema; perfect for snapshot tests or telemetry pipelines.
  • SARIF: Export machine-readable reports for GitHub Advanced Security or Azure DevOps.
  • Overlay: Toggleable in-app visualization to help engineers resolve issues in context.

Rule Catalogue (Core)

| Rule | Severity | WCAG Reference | | --- | --- | --- | | img-alt-missing | major | SC 1.1.1 Non-text Content | | interactive-aria-missing | critical | SC 4.1.2 Name, Role, Value | | keyboard-tabindex-misuse | critical | SC 2.1.1 Keyboard | | contrast-text-aa | major/critical | SC 1.4.3 Contrast (Minimum), SC 1.4.6 Contrast (Enhanced) | | form-label-missing | major/critical | SC 1.3.1 Info & Relationships, SC 3.3.2 Labels or Instructions | | duplicate-id | major | SC 4.1.1 Parsing | | language-attr-missing | major | SC 3.1.1 Language of Page | | focus-indicator-missing | major | SC 2.4.7 Focus Visible | | iframe-cross-origin | info/major | SC 4.1.2 Name, Role, Value |

Extensibility

controller.registerRule({
  id: 'custom-rule',
  title: 'Example',
  description: 'Checks something bespoke.',
  severity: 'minor',
  matcher: (root) => Array.from(root.querySelectorAll('[data-check]')),
  evaluate: (element) => ({
    ruleId: 'custom-rule',
    selector: '',
    severity: 'minor',
    message: 'Element requires data-check description.',
    why: 'Internal accessibility standard.',
    context: '',
    suggestion: {
      operation: 'addAttribute',
      patch: 'add data-check="description"',
      example: '<div data-check="description"></div>',
    },
  }),
});

Custom formatters can be registered via controller.getMetrics() and the exported formatter factory utilities.

Privacy & Telemetry

  • Telemetry is disabled by default. No DOM or text content leaves the device unless explicitly configured.
  • maskTextContent redacts visible text in context outputs.
  • Telemetry payloads hash message strings via a deterministic, non-reversible hash before transmission.

Performance

  • Incremental rescans use MutationObserver sub-tree queues and idle callbacks.
  • performanceMode presets balance latency versus coverage:
    • aggressive: fastest turnaround (small debounce window)
    • balanced: default (250 ms debounce)
    • light: minimal CPU usage for lower-priority environments
  • controller.getMetrics() exposes scan timing, issue counts, and node coverage for dashboards.

Testing

  • Unit: Rule matcher/evaluator behavior via Vitest and JSDOM.
  • Integration: SPA route changes, MutationObserver latency, Shadow DOM fixtures, same-origin iframe traversal.
  • E2E: Playwright automation sampling overlay toggles and console output.
  • Snapshots: Serialize ScanResult arrays to assert expected issues (maskTextContent for PII).

Sample package.json scripts:

{
  "scripts": {
    "lint": "eslint 'src/**/*.{ts,tsx}'",
    "test": "vitest run",
    "test:e2e": "vitest run --config vitest.e2e.config.ts",
    "a11y:scan": "a11y-scan --file dist/index.html --format sarif"
  }
}

CI Integration (GitHub Actions excerpt)

name: accessibility

on: [push, pull_request]

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v2
      - run: pnpm install
      - run: pnpm build
      - run: pnpm test
      - run: pnpm exec a11y-scan --file dist/index.html --format sarif

Roadmap

  • MVP: Core DOM scanner, overlay, JSON/console reporters, MutationObserver + SPA support.
  • v1.0: SARIF exporter, framework adapters, telemetry scrubbing, Playwright harness, CLI packaging.
  • v2.0: Visual regression annotations, IDE extensions, browser extension packaging, collaborative dashboards.

Versioning & Releases

  • Semantic Versioning (SemVer) compliance (MAJOR.MINOR.PATCH).
  • Maintain CHANGELOG.md via Keep a Changelog format.
  • Before publishing: run pnpm build && pnpm test, verify npm pack, update changelog, tag release.

NPM Publishing Workflow

  1. Update package.json metadata (name, version, description, keywords).
  2. pnpm build
  3. npm login
  4. npm publish --access public