CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/axe-a11y

Automated accessibility scanning across the five engines - axe-core (primary), pa11y, Lighthouse a11y, WAVE, and IBM Equal Access. Authors and runs axe-core scans via the `axe.run()` JavaScript API or the @axe-core/playwright / @axe-core/cli wrappers, parses `violations[]` into per-rule severity, configures rule disable / disable-by-tag patterns, and emits CI-gateable output; references/ carry the pa11y CLI (htmlcs + axe runners), Lighthouse CI `categories:accessibility` assertions, the WAVE API / overlay, and IBM Equal Access (Section 508) with their verified CLI / API / config. Use for any automated a11y scanner setup - axe-core for JS/TS UI test suites on every PR, and the references for CLI-only, Lighthouse-pipeline, WebAIM-branded, or Section 508 scanning.

75

Quality

94%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

pa11y.mdreferences/

pa11y - CLI scanner (htmlcs + axe engines)

Companion reference for axe-a11y. Consult when the project needs scriptable a11y scans without a full test framework (CI cron job, docs publication, static-site CI), or when a Node-stack project wants a single-command scanner instead of framework-integrated axe tests.

pa11y is "your automated accessibility testing pal" - a Node.js CLI that runs a11y tests on a page via the command line or a programmatic API (pa11y). It can use HTML CodeSniffer (htmlcs, default) or axe-core as the underlying engine. If the project already runs Playwright / Cypress with axe-core, prefer the direct axe integration in SKILL.md - pa11y adds a layer.

Install and run

npm install -g pa11y        # or --save-dev per-project
pa11y https://example.com

(Per pa11y.)

Key flags

FlagEffect
--reporter <name>Output format: cli (default), csv, json, html, tsv.
--standard <name>WCAG standard: WCAG2A, WCAG2AA (default), WCAG2AAA.
--runner <name>Engine: htmlcs (default) or axe; repeat to run both.
--include-warningsInclude warning-level issues (excluded by default).
--include-noticesInclude notice-level issues.
--ignore <rules>Skip specific rules (comma-separated).
--threshold <n>Allow up to N issues before failing (exit-code gate).
--timeout <ms>Page-load timeout.
--config <file>Use a .pa11yrc config file.

pa11y's WCAG2AA standard is 2.0/2.1; WCAG 2.2 SCs (2.4.11, etc.) need --runner axe alongside htmlcs.

Multi-URL with pa11y-ci

pa11y-ci (https://github.com/pa11y/pa11y-ci) batches a URL set from a .pa11yci config and exits non-zero if any URL exceeds threshold - the canonical CI gate signal:

{
  "defaults": {
    "standard": "WCAG2AA",
    "runners": ["axe", "htmlcs"],
    "includeWarnings": true,
    "threshold": 0
  },
  "urls": [
    "https://staging.example.com/",
    "https://staging.example.com/dashboard",
    "https://staging.example.com/checkout"
  ]
}

Programmatic API and results structure

const pa11y = require('pa11y');

const results = await pa11y('https://example.com', {
  standard: 'WCAG2AA',
  runners: ['axe', 'htmlcs'],
  includeWarnings: true,
});

console.log(results.issues);

results.issues[] holds one object per finding with code, type (error / warning / notice), typeCode, selector, context, message, and runner. When both engines run, the same defect appears twice under different codes - WCAG-SC-coded from htmlcs (WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail), rule-coded from axe (color-contrast) - and a11y-violation-gate collapses the pair via its fingerprint field.

Worked example

pa11y --standard WCAG2AA \
      --runner htmlcs --runner axe \
      --include-warnings \
      --reporter json \
      --threshold 0 \
      https://staging.example.com/checkout > pa11y-results.json

The run exits non-zero (threshold 0 exceeded) and pa11y-results.json holds the issues[] array for the gate.

Anti-patterns

Anti-patternWhy it failsFix
Default WCAG2AA without WCAG 2.2 specificsThe htmlcs standard is 2.0/2.1; 2.2 SCs need the axe runner.Always include --runner axe.
Threshold 0 on a project with debtEvery PR fails until the entire backlog is fixed.Use a11y-violation-gate ratchet OR raise threshold incrementally.
Running only htmlcsDifferent rule coverage than axe; misses issues.Run both runners; deduplicate at the gate.
Ignoring rules without config commentsLost institutional knowledge.Inline justification + quarterly review.

Limitations

  • Selector reliability. htmlcs sometimes produces selectors that don't uniquely identify the failing element; axe is more precise.
  • JS-rendered content. pa11y's default Chromium runner waits for the load event; SPAs may need --wait-for-selector before scanning.
  • No native test-framework integration. For Playwright / Cypress, use the direct axe integration in SKILL.md.

References

SKILL.md

tile.json