The Developer's Quarterly · AccessibilityVol. II · February 2026

a11y:How to Install the Core Accessibility Tools

Accessibility is a workflow you add to your stack: install static linting first, then rendered DOM checks, then Storybook review tools so problems surface early.

If you are building React interfaces, accessibility usually starts as a small checklist item and turns into a toolchain decision. The shorthand a11y is not a package you install. It is the habit of adding checks at the points where UI bugs are easiest to catch: static linting, rendered DOM tests, and component review tools.

That is the useful frame for a short setup guide. You do not need one giant accessibility framework. You need a few focused tools that catch different classes of problems before they ship.

Start with the right mental model

Accessibility tooling works best when you treat it like layers in a pipeline.

1 Static JSX linting

Use it to catch missing labels, invalid ARIA usage, and bad semantic patterns before a component runs.

2 Rendered DOM checks

Use it to inspect the markup a component actually produces after React renders it.

3 Story-level review

Use it when designers and developers need to inspect isolated components in a predictable environment.

4 Human verification

Keep keyboard and screen reader testing in the loop for flows that real users depend on.

Install the linting layer first

For React projects, the usual first install is eslint-plugin-jsx-a11y. It adds JSX-specific rules that catch a lot of avoidable mistakes before the app even runs.

Install the ESLint plugin
npm install -D eslint-plugin-jsx-a11y

If you are using ESLint flat config, you can start from the plugin's recommended config and then add a few project-specific rules:

ESLint flat config
import jsxA11y from 'eslint-plugin-jsx-a11y'; export default [ jsxA11y.flatConfigs.recommended, { files: ['**/*.{js,mjs,cjs,jsx,ts,tsx}'], rules: { 'jsx-a11y/no-autofocus': 'warn', 'jsx-a11y/interactive-supports-focus': 'error', 'jsx-a11y/label-has-associated-control': 'error', }, }, ];

That gives you a fast feedback loop for missing labels, invalid roles, and interactive elements that are not actually keyboard friendly.

Add rendered DOM checks next

Linting is necessary, but it does not see the final rendered output. For that layer, jest-axe is a common choice because it runs the axe accessibility engine against the DOM your component actually produced.

Install test-time accessibility tools
npm install -D jest-axe @testing-library/react @testing-library/jest-dom

Then write a focused component test:

Axe test with React Testing Library
import { render } from '@testing-library/react'; import { axe, toHaveNoViolations } from 'jest-axe'; expect.extend(toHaveNoViolations); it('keeps the dialog accessible', async () => { const { container } = render( <button type="button" aria-label="Save changes"> Save </button> ); const results = await axe(container); expect(results).toHaveNoViolations(); });

That pattern is useful because it checks the rendered markup, not just the source code. It will not guarantee that the UI is truly accessible, but it will catch many structural errors quickly.

Add Storybook checks for component review

Storybook is a good place to review accessibility because it isolates components from the rest of the application. The accessibility addon uses axe-core to scan a story while you are looking at it.

Add the Storybook addon
npx storybook add @storybook/addon-a11y

If you manage the config manually, the addon entry is straightforward:

Storybook main config
const config = { addons: ['@storybook/addon-a11y'], }; export default config;

That is especially helpful for design systems, where many people need to inspect the same button, dialog, or form field in a controlled environment.

Compare the layers

Tool Install step Best for Main limit
eslint-plugin-jsx-a11y npm install -D eslint-plugin-jsx-a11y Catching semantic mistakes in JSX before code runs It only sees static code
jest-axe npm install -D jest-axe @testing-library/react @testing-library/jest-dom Checking the rendered DOM in unit or component tests It cannot replace real assistive-tech testing
@storybook/addon-a11y npx storybook add @storybook/addon-a11y Reviewing isolated components during development It depends on how well your stories mirror reality
Keyboard and screen reader testing No install command Verifying the actual user experience It still takes human time and judgment

Practical rules that keep the stack useful

Install linting first Start with static checks so the cheapest problems fail earliest in the workflow.
Gate CI with DOM tests Use rendered accessibility tests on the components and interactions that matter most.
Review stories where the team works Storybook is a good place to keep shared components visible and easy to inspect.
Keep humans in the loop Manual keyboard and screen reader testing is still the final check for user-facing flows.

The biggest mistake teams make is assuming a single tool is enough. A lint rule can tell you that an image needs alt text. A DOM test can tell you that a dialog opens with the right structure. Neither one can tell you whether the whole interaction makes sense when someone is using a screen reader and keyboard only.

Bottom line

Accessibility is not a separate project you start after the UI is done. It is a set of checks you install into the workflow you already have.

Start with eslint-plugin-jsx-a11y, add jest-axe for rendered component tests, and wire in @storybook/addon-a11y where your team reviews UI. Then keep the human review step in the loop, because the final accessibility test is still a real person using the interface.