DEV Community

Thesius Code
Thesius Code

Posted on • Originally published at datanest-stores.pages.dev

Accessibility Audit Toolkit

Accessibility Audit Toolkit

A comprehensive WCAG 2.1 compliance toolkit that gives frontend teams everything they need to build inclusive web applications. Includes automated audit configurations for axe-core and Lighthouse, screen reader testing scripts for NVDA/VoiceOver/JAWS, a complete ARIA pattern library with copy-paste components, and a structured checklist that maps every WCAG 2.1 success criterion to actionable code changes. Stop guessing at accessibility — ship with confidence.

Key Features

  • WCAG 2.1 Level AA Checklist — 78 success criteria mapped to specific HTML/ARIA fixes with code examples for each
  • axe-core Configuration Pack — Pre-built rule sets for CI pipelines, including custom rules for SPA-specific issues like focus management
  • Screen Reader Testing Scripts — Step-by-step test scripts for NVDA (Windows), VoiceOver (macOS/iOS), and TalkBack (Android)
  • ARIA Pattern Library — 25+ accessible component patterns: modals, tabs, accordions, comboboxes, data grids, and tree views
  • Lighthouse CI Integration — GitHub Actions workflow that blocks PRs failing accessibility thresholds
  • Color Contrast Analyzer — Utility functions to validate contrast ratios against WCAG AA/AAA standards programmatically
  • Keyboard Navigation Audit — Focus trap utilities, skip-link patterns, and roving tabindex implementations

Quick Start

  1. Extract the archive into your project root
  2. Install the axe-core dev dependency:
npm install --save-dev @axe-core/react axe-core
Enter fullscreen mode Exit fullscreen mode
  1. Add the audit script to your app's development entry point:
// src/lib/a11y-dev.ts
import React from 'react';
import ReactDOM from 'react-dom';

if (process.env.NODE_ENV === 'development') {
  import('@axe-core/react').then((axe) => {
    axe.default(React, ReactDOM, 1000, {
      rules: [
        { id: 'color-contrast', enabled: true },
        { id: 'label', enabled: true },
        { id: 'aria-roles', enabled: true },
      ],
    });
  });
}
Enter fullscreen mode Exit fullscreen mode
  1. Run the Lighthouse CI audit:
npx lhci autorun --config=./a11y-toolkit/lighthouserc.json
Enter fullscreen mode Exit fullscreen mode

Architecture / How It Works

The toolkit is organized into four layers that work independently or together:

accessibility-audit-toolkit/
├── checklist/               # WCAG 2.1 criterion-by-criterion checklist
│   ├── perceivable.md       # 1.x criteria (images, captions, contrast)
│   ├── operable.md          # 2.x criteria (keyboard, timing, seizures)
│   ├── understandable.md    # 3.x criteria (readable, predictable, input)
│   └── robust.md            # 4.x criteria (parsing, name/role/value)
├── configs/                 # Automated testing configurations
│   ├── axe-core.config.ts   # axe-core rule customization
│   ├── lighthouserc.json    # Lighthouse CI thresholds
│   └── jest-axe.setup.ts    # Jest + axe integration
├── patterns/                # ARIA component patterns
│   ├── dialog-modal.tsx     # Accessible modal with focus trap
│   ├── tabs.tsx             # ARIA tabs with roving tabindex
│   ├── combobox.tsx         # Autocomplete combobox pattern
│   └── ...                  # 22 more patterns
└── scripts/                 # Screen reader test scripts
    ├── nvda-test-plan.md
    ├── voiceover-test-plan.md
    └── keyboard-audit.md
Enter fullscreen mode Exit fullscreen mode

Usage Examples

Jest + axe-core Integration Test

import { render } from '@testing-library/react';
import { axe, toHaveNoViolations } from 'jest-axe';
import { LoginForm } from './LoginForm';

expect.extend(toHaveNoViolations);

test('LoginForm has no accessibility violations', async () => {
  const { container } = render(<LoginForm />);
  const results = await axe(container);
  expect(results).toHaveNoViolations();
});
Enter fullscreen mode Exit fullscreen mode

Configuration

axe-core Rule Customization (axe-core.config.ts)

export const axeConfig = {
  rules: {
    // Enforce stricter contrast for large text
    'color-contrast-enhanced': { enabled: true },
    // Disable rules that conflict with your design system
    'region': { enabled: false },
  },
  // Only audit the main content area (skip third-party widgets)
  context: '#app-root',
  // Set minimum impact level to report
  resultTypes: ['violations', 'incomplete'],
};
Enter fullscreen mode Exit fullscreen mode

Lighthouse CI Thresholds (lighthouserc.json)

{
  "ci": {
    "assert": {
      "assertions": {
        "categories:accessibility": ["error", { "minScore": 0.95 }],
        "color-contrast": "error",
        "label": "error",
        "image-alt": "error"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Best Practices

  • Test with real screen readers — automated tools catch ~30% of accessibility issues; manual testing catches the rest
  • Add accessibility tests to CI — use the included GitHub Actions workflow to block inaccessible PRs before merge
  • Use semantic HTML first — reach for ARIA only when native elements can't express the interaction pattern
  • Test keyboard navigation paths — every interactive element must be reachable and operable via keyboard alone
  • Announce dynamic content — use aria-live regions for toast notifications, form errors, and loading states
  • Validate with real users — schedule quarterly testing sessions with users who rely on assistive technology

Troubleshooting

Issue Cause Fix
axe reports violations inside third-party components axe scans the full DOM by default Set context in config to scope scanning to your app root
Focus trap doesn't work in modal Portal renders outside the trap container Mount the focus trap inside the portal wrapper, not outside it
Lighthouse CI fails but site looks fine Score thresholds are set too strict for initial adoption Lower minScore to 0.85, then increment by 0.02 each sprint
Screen reader skips dynamic content Missing aria-live attribute on updated region Add aria-live="polite" to the container that receives dynamic updates

This is 1 of 11 resources in the Frontend Developer Pro toolkit. Get the complete [Accessibility Audit Toolkit] with all files, templates, and documentation for $29.

Get the Full Kit →

Or grab the entire Frontend Developer Pro bundle (11 products) for $129 — save 30%.

Get the Complete Bundle →


Related Articles

Top comments (0)