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

@a13y/devtools

v0.1.5

Published

Development-time validators and runtime checks for @a13y (tree-shakeable)

Readme

@a13y/devtools

Development-time validators and runtime checks for @a13y

Helpful warnings and error messages during development, automatically stripped in production.

npm version License: MIT


Features

  • Development-only - Zero overhead in production (tree-shakeable)
  • WCAG references - Every warning includes WCAG 2.2 criterion
  • Fix suggestions - Actionable fixes with code examples
  • Runtime validation - Catches accessibility issues during development
  • Type-safe - Full TypeScript support

Installation

npm install -D @a13y/devtools

Usage

Devtools are automatically integrated when you use @a13y/react or @a13y/core. Simply install the package and warnings will appear in development.

Automatic Integration

import { useAccessibleButton } from '@a13y/react';

function Button() {
  const { buttonProps } = useAccessibleButton({ onPress: () => {} });

  // ⚠️ Warning in console if devtools installed:
  // "Element is missing accessible label (WCAG 4.1.2)"
  return <button {...buttonProps}></button>;
}

Manual Validation

You can also use validators directly:

import { validateFocus, validateAria } from '@a13y/devtools/runtime/validators';

const button = document.querySelector('button');

// Validate focus management
validateFocus(button, {
  hasFocusableElements: true,
  isVisible: true,
});

// Validate ARIA attributes
validateAria(button, {
  role: 'button',
  requiredAttrs: ['aria-label'],
});

Validators

Focus Validator

import { validateFocus } from '@a13y/devtools/runtime/validators';

validateFocus(element, {
  hasFocusableElements: true,
  isVisible: true,
  isInert: false,
});

Checks:

  • Element has focusable children
  • Focus trap contains interactive elements
  • Elements are visible
  • No inert ancestors

ARIA Validator

import { validateAria } from '@a13y/devtools/runtime/validators';

validateAria(element, {
  role: 'dialog',
  requiredAttrs: ['aria-labelledby', 'aria-describedby'],
  allowedRoles: ['dialog', 'alertdialog'],
});

Checks:

  • Valid ARIA roles
  • Required ARIA attributes present
  • Attribute values are valid
  • No conflicting attributes

Keyboard Validator

import { validateKeyboard } from '@a13y/devtools/runtime/validators';

validateKeyboard(element, {
  supportsKeys: ['Enter', ' ', 'Escape'],
  hasKeyboardHandler: true,
});

Checks:

  • Keyboard event handlers present
  • Required keys supported
  • Focus visible on keyboard navigation

Warning System

Warning Levels

import { warn, error } from '@a13y/devtools/runtime/warnings';

// Polite warning (logged to console)
warn('accessibility-issue', {
  message: 'Missing accessible label',
  wcagCriterion: '4.1.2',
  fixes: [
    'Add aria-label attribute',
    'Add aria-labelledby reference',
    'Add visible text content',
  ],
});

// Error (thrown in dev, silent in prod)
error('critical-accessibility-issue', {
  message: 'Dialog missing required title',
  wcagCriterion: '2.4.6',
});

Warning Categories

  • focus - Focus management issues
  • keyboard - Keyboard navigation problems
  • aria - ARIA attribute errors
  • structure - DOM structure issues
  • semantics - Semantic HTML problems

Invariants

Runtime checks that throw errors in development:

import { invariant } from '@a13y/devtools/runtime/invariants';

invariant(
  element.hasAttribute('aria-label'),
  'Button must have accessible label',
  'WCAG 4.1.2'
);

Production Builds

All devtools code is automatically removed in production:

// Development build
if (process.env.NODE_ENV !== 'production') {
  validateFocus(element);
}

// Production build - entire block removed by bundler
// No runtime overhead!

Configuration

Configure warning behavior:

import { configureWarnings } from '@a13y/devtools';

configureWarnings({
  // Disable specific warnings
  ignore: ['focus-trap-no-elements'],

  // Throw errors instead of warnings
  strict: true,

  // Custom warning handler
  onWarn: (warning) => {
    console.log(`[A13Y] ${warning.message}`);
    // Send to error tracking service
  },
});

TypeScript Support

Full TypeScript support with type definitions:

import type {
  WarningType,
  ValidationOptions,
  WCAGCriterion,
} from '@a13y/devtools';

Example Warnings

Missing Label

⚠️ A13Y Warning: Missing accessible label
Element: <button>Save</button>
WCAG: 4.1.2 Name, Role, Value

Suggested fixes:
1. Add aria-label: <button aria-label="Save document">
2. Add aria-labelledby: <button aria-labelledby="save-label">
3. Ensure visible text is descriptive

Invalid ARIA

⚠️ A13Y Warning: Invalid ARIA attribute value
Element: <div role="dialog" aria-expanded="yes">
WCAG: 4.1.2 Name, Role, Value

Issue: aria-expanded must be "true" or "false", not "yes"

Fix: <div role="dialog" aria-expanded="true">

Focus Trap

⚠️ A13Y Warning: Focus trap has no focusable elements
Element: <div role="dialog">...</div>
WCAG: 2.1.1 Keyboard

Issue: Focus trap activated but contains no focusable elements

Suggested fixes:
1. Add focusable elements (button, input, a, etc.)
2. Add tabindex="0" to make element focusable
3. Check if elements are hidden or disabled

Tree Shaking

Import validators individually for optimal bundle size:

// ✅ Good - imports only focus validator
import { validateFocus } from '@a13y/devtools/runtime/validators';

// ❌ Avoid - imports all validators
import { validateFocus } from '@a13y/devtools';

Author

Created and maintained by Diego Aneli (@DiegoAneli)

License

MIT © Diego Aneli and contributors