Automated checks: axe-core, Lighthouse, WAVE
Three tools every team reaches for first — what each one is good at, what each one cannot see, and the rule that keeps you honest.
When someone says "we run a11y checks," they almost always mean automated checks — scripts that crawl the rendered DOM and flag rules they understand. They are fast, cheap, and great at catching the boring mistakes. They are also the smaller part of the job.
Before we look at any single tool, you need a number stuck in your head: automation catches roughly 30% of accessibility issues. The rest — whether the keyboard order makes sense, whether a button announces what it actually does, whether your custom modal traps focus — needs a human. We start with automation because it removes the noise so the human attention you have left can go where it matters.
The 30% rule
You will see this called "the 30% rule" or "the rule of thirds." It comes from research by Deque (the company behind axe-core) and several independent audits: scanners reliably detect about a third of the WCAG violations a trained auditor would find on the same page. They miss things they cannot infer from the DOM alone — things like meaning, order, and context.
Automated tools are a floor, not a ceiling. Zero violations doesn't mean accessible. It means you cleared the easy ones and earned the right to do the hard part.
Practically, here's what a scanner can tell you:
- "This image has no alt text."
- "These two colors don't meet 4.5:1 contrast."
- "This input has no associated label element."
- "This page has no
<main>landmark."
And here's what it cannot:
- "The alt text says
image1.png— that's technically present, just useless." - "Tab order goes header → footer → middle content."
- "The 'Submit' button actually deletes the user's account."
- "This dialog is announced as 'group' instead of 'dialog'."
Keep that split in mind as we look at three tools.
axe-core
axe-core is the testing engine — a JavaScript library, open source, maintained by Deque. By itself it's just a function: feed it a DOM, get back a list of violations, passes, and incomplete checks. The reason you'll hit it everywhere is that almost every other tool wraps it: the axe DevTools browser extension, jest-axe, Playwright's @axe-core/playwright, Lighthouse itself. They share the same rule set.
<!-- Drop into the page, open DevTools console -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/axe-core/4.8.0/axe.min.js"></script>
<script>
axe.run().then(results => {
console.log(results.violations);
});
</script>Each violation tells you the rule that fired (e.g. color-contrast), the impact (minor / moderate / serious / critical), the exact node it found, and a link to a remediation guide. That structured output is why axe is so easy to plug into automation later.
axe will sometimes report incomplete results — checks it couldn't run automatically, like "is this image actually decorative?" Treat those as TODOs for the human pass, not as passes.
The browser extension is the friendliest entry point. Open DevTools, click the axe panel, hit "Scan." For every issue it shows you the offending element, the rule it broke, and a one-paragraph fix. That feedback loop — see issue, fix, re-scan — is what makes it a daily-driver tool, not just an audit tool.
Lighthouse
Lighthouse is built into Chrome DevTools (the "Lighthouse" tab) and runs four audits at once: Performance, Accessibility, Best Practices, SEO. The accessibility section also runs axe-core under the hood — but with a smaller, curated rule subset. So a Lighthouse score of 100 doesn't mean axe-clean; it means it passed the rules Lighthouse chose to include.
What Lighthouse adds on top of axe is a single number — the score from 0 to 100. That number is genuinely useful for one thing: tracking direction over time. "We were at 78 last month, we're at 92 now" is a story product managers understand. Don't let it become the goal, though — a 100 score with a still-broken keyboard flow is worse than an 82 score with an audit-tracked plan.
Lighthouse also runs in CI as a Node module (lighthouse-ci), and you can set thresholds — fail the build if the accessibility score drops below 90, for example. That's a reasonable gate for a project that has never had accessibility checks before. Once you mature, you'll want stricter rules from axe directly.
WAVE
WAVE — short for Web Accessibility Evaluation Tool — is from WebAIM. It's a browser extension and a hosted page (wave.webaim.org). What sets it apart is the visual overlay: instead of a list of violations, it draws icons directly onto the page next to each issue. Red icons are errors, yellow are alerts, green are features (things you got right).
For non-developers — designers, content people, project managers — WAVE is often the easiest tool to read. They can literally see a red marker next to the broken thing. For developers it's a useful second opinion: WAVE uses its own rule engine, not axe, so it sometimes catches things axe misses (and vice versa).
Run a page through both axe and WAVE the first time you audit it. The overlap is your high-confidence findings; the diff is worth a second look in either direction.
A small wrinkle: the hosted version of WAVE only sees the initial HTML response, not the rendered DOM, so single-page apps need the extension version to be evaluated properly. Same trap exists for any tool that fetches the URL server-side.
Picking between them
You don't need to pick one — most teams use two or three for different jobs. A rough cheat sheet:
| Tool | Best for | Lives in |
|---|---|---|
| axe DevTools | Daily dev loop, deep details, exact remediation | Browser extension |
| jest-axe | Catching component-level violations in unit tests | Test runner |
| Lighthouse | Trend score, exec dashboards, baseline CI gate | Chrome DevTools, lighthouse-ci |
| WAVE | Sharing findings with non-engineers, second opinion | Browser extension |
| @axe-core/playwright | Scanning real pages in end-to-end tests | Playwright |
The deeper point is that all of these are running variants of the same handful of rule engines. Stacking three of them does not get you to 90% coverage — it gets you to maybe 35%. The other 65 still needs hands and ears.