Skip to main content
Up Your A11y

Tooling, Revisited

The tooling advice on this site is several years old. What has held up, what has been replaced, and what is now worth adding to a pipeline rather than a browser.

For developers who want to:

  • Know which of the original tool recommendations still stand
  • Move some checks out of the browser and into the pipeline
  • Understand what automated tools can and cannot find
  • Set up a check that runs on every pull request

The tooling article on this site was written some years ago. Most of it still stands — the underlying engines have not changed much — but the useful place to run these checks has moved.

What has held up

The browser extensions. Axe and WAVE are still the fastest way to check a page you are looking at, and still the right first thing to install.

The browser's own accessibility inspector. Firefox and Chrome both ship one now, and the accessibility tree view is the quickest way to answer "what does an assistive technology actually see here".

Contrast checkers. Unchanged in principle. Worth noting that WCAG 2.2 added a AAA criterion on focus indicator appearance, so contrast now applies to your focus ring, not just your text.

The screen reader. Still the thing that finds what nothing else does, and still the thing most developers skip.

What has moved

The significant change is not which tools exist, but where they run.

Checking a page in the browser finds problems after they are built. The same engine can run in your test suite and in continuous integration, where it finds them before they merge.

The linter. A JSX accessibility linter catches a real class of mistakes — missing alt, invalid ARIA, click handlers on non-interactive elements — at the moment they are typed, which is by far the cheapest place to catch them.

Component-level checks. Running the axe engine against a rendered component in your unit tests catches regressions in the component itself, in isolation, without needing a page.

Pipeline checks. The same engine run against key pages on every pull request. This is what stops a fixed problem from quietly coming back.

The three layers cover different things and none replaces another.

What automated tools find

Worth being precise, because the figure is widely misquoted in both directions.

Automated checks find a minority of accessibility problems. They are extremely good at the mechanical, machine-decidable ones: missing alt attributes, invalid ARIA, insufficient colour contrast on plain text, missing form labels, duplicate ids.

They cannot judge whether alt text is appropriate, whether the reading order makes sense, whether a drag alternative is equivalent, whether help is in a consistent place, or whether a focus indicator is actually findable.

Most of the criteria added in WCAG 2.2 fall in the second category. That makes the manual pass more important now than it was when the original article was written, not less.

A practical setup

If you are starting from nothing, in order of return:

One: a JSX accessibility linter in your editor and in CI, with warnings failing the build. Cheapest possible fix point.

Two: a browser extension you actually use, on the page you are working on.

Three: the axe engine in your component tests, for the components that matter.

Four: a screen reader on your own machine, used on the main flows once per feature rather than once per year.

Five: a pipeline check on key pages.

The first two take an afternoon. The rest can arrive over months.

The one that people skip

Every list of accessibility tooling ends with "and test with a screen reader", and most teams never do.

It is worth being blunt about why that matters: the automated layers above are checking whether your markup follows rules. The screen reader is checking whether the result is usable. Those are different questions, and only one of them is the point.

Fifteen minutes on your own main flow, with the screen reader you already have installed, will find more than a week of tuning your lint configuration.

[Suzanne: the original tooling article names specific extensions with screenshots, and four of those screenshots did not survive archiving. If you still have them, they belong there. This piece is deliberately written as an update alongside it rather than a replacement.]