type: service
status: active
timestamp: 2026-06-20
tags: [a11y, accessibility, axe, ci, primary]

axe-core

Industry-standard a11y rule engine; @axe-core/playwright in CI

axe-core

Role

Static-rule a11y engine — runs Deque’s WCAG 2.1 / 2.2 ruleset against rendered pages and emits violations. The family runs @axe-core/playwright in every site’s PR CI as one of the three a11y tools; PR fails on any new violation.

Free tier

Card / subscription required?

NO. OSS — installed via pnpm add -D @axe-core/playwright.

How CI consumes it

// tests/a11y.spec.ts
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';

test.describe('a11y (axe)', () => {
  for (const path of ['/', '/about', '/support']) {
    test(`no violations on ${path}`, async ({ page }) => {
      await page.goto(path);
      const results = await new AxeBuilder({ page })
        .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
        .analyze();
      expect(results.violations).toEqual([]);
    });
  }
});

Runs alongside the Pa11y and Lighthouse CI jobs in the same PR.

What it catches

Alternatives

Swap cost

Medium — axe is the de-facto a11y rule engine; Pa11y can run axe as its backend, so dropping @axe-core/playwright and pointing Pa11y at axe-runner keeps coverage. Test files would need rewriting.

Why this is our pick

The industry-standard ruleset — Deque maintains it, Microsoft and Google contribute. Playwright integration runs in the existing browser context (no extra infrastructure). Free, OSS, unlimited. Pairs with Pa11y (different ruleset) and Lighthouse CI (scoring) for three-tool a11y coverage.

Cross-refs


Edit on GitHub · Back to index