How to Use the a11y Addon for Accessibility Testing in Storybook
The a11y addon integrates axe-core directly into Storybook to automatically detect accessibility violations in your components during development.
The @storybook/addon-a11y package provides an out-of-the-box solution for automated accessibility testing within the storybookjs/storybook ecosystem. By injecting axe-core into the preview iframe, the addon analyzes rendered components against WCAG standards and displays violations directly in the Storybook UI.
What Is the Storybook a11y Addon?
The a11y addon is an official Storybook extension that runs automated accessibility audits using axe-core. It consists of three architectural components working together to provide real-time feedback:
- Runner (
a11yRunner.ts) – Executes axe-core tests against the rendered story - Utilities (
a11yRunnerUtils.ts) – Formats results and filters violations - Integration layer – Registers the addon with Storybook's manager UI and exposes the
runA11yAPI
When Storybook renders a story, the addon automatically injects the axe script, runs checks, and displays any violations in the dedicated Accessibility panel.
Installation and Basic Setup
Install the Package
Add the addon to your development dependencies using npm or yarn:
npm install --save-dev @storybook/addon-a11y
Register the Addon
Update your .storybook/main.js configuration to include the a11y addon in the addons array:
module.exports = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-a11y',
// other addons
],
};
Once registered, Storybook will display the ⚙️ A11y toolbar button and the Accessibility panel in the addon sidebar.
Configuring Accessibility Testing Globally
You can set default accessibility parameters for all stories by exporting a parameters object from .storybook/preview.js:
export const parameters = {
a11y: {
// Enable automatic checking on every story
disable: false,
// Configure axe-core options
config: {
rules: [
{ id: 'color-contrast', enabled: true },
{ id: 'heading-order', enabled: true }
],
},
// Options for the axe.run() method
options: {
runOnly: {
type: 'tag',
values: ['wcag2a', 'wcag2aa', 'wcag21aa']
}
}
},
};
The config object maps directly to axe-core's configuration, allowing you to enable or disable specific rules globally.
Running Accessibility Checks Per Story
Using the withA11y Decorator
For granular control, apply the withA11y decorator to individual stories or component defaults:
import { withA11y } from '@storybook/addon-a11y';
export default {
title: 'Components/Button',
component: Button,
decorators: [withA11y],
};
export const Primary = {
args: {
primary: true,
label: 'Click me',
},
};
You can also disable accessibility checking for specific stories using parameters:
export const HiddenFromA11y = {
parameters: {
a11y: {
disable: true,
},
},
};
Accessing Results in the Accessibility Panel
After loading a story, click the ⚙️ A11y toolbar button to open the Accessibility panel. The interface displays:
- Violations – Elements that fail WCAG criteria with severity levels (minor, moderate, serious, critical)
- Passes – Rules that passed successfully
- Incomplete – Rules that require manual review
Each violation includes the element selector, impact level, and a link to detailed remediation guidance.
Programmatic Accessibility Testing with runA11y
The a11y addon exposes a runA11y function for use in automated test suites or CI pipelines. This allows you to reuse Storybook's accessibility configuration in Jest or other testing frameworks.
import { runA11y } from '@storybook/addon-a11y';
import { render } from '@testing-library/react';
import MyComponent from './MyComponent';
test('should have no accessibility violations', async () => {
const { container } = render(<MyComponent />);
const results = await runA11y(container);
expect(results.violations).toHaveLength(0);
});
The runA11y function accepts a DOM element or document context and returns a promise resolving to the axe results object, containing violations, passes, incomplete, and inapplicable arrays.
How the a11y Addon Works Under the Hood
The a11yRunner.ts Execution Engine
Located at code/addons/a11y/src/a11yRunner.ts, the a11yRunner serves as the core execution engine. It creates an axe context from the rendered story's DOM, merges default rules with user-provided configuration from parameters.a11y, and invokes axe.run().
The runner handles the asynchronous communication between the preview iframe and the Storybook manager, ensuring that accessibility checks complete before results display in the UI.
Result Processing in a11yRunnerUtils.ts
The code/addons/a11y/src/a11yRunnerUtils.ts file contains utility functions that transform raw axe-core output into Storybook-compatible message formats. These utilities filter violations by impact level, deduplicate results across component variations, and format element selectors for the Accessibility panel display.
The a11yRunnerUtils.test.ts file provides unit test coverage ensuring that result formatting behaves consistently across different violation types and DOM structures.
Summary
- Install
@storybook/addon-a11yand register it in.storybook/main.jsto enable automated accessibility testing - Configure global axe-core rules in
.storybook/preview.jsusing theparameters.a11yobject - Apply the
withA11ydecorator to individual stories for granular control over accessibility checks - View detailed violation reports in the Accessibility panel, including severity levels and remediation links
- Use the
runA11yfunction programmatically in Jest or CI pipelines to enforce accessibility standards in automated tests
Frequently Asked Questions
How do I disable accessibility checks for a specific story?
Add the a11y parameter with disable: true to the story's export object. This prevents the axe-core runner from executing on that specific component while keeping checks enabled globally for other stories.
Can I customize the axe-core rules in the a11y addon?
Yes. Pass a config object within parameters.a11y to enable or disable specific rules. You can also provide an options object to control which WCAG tags to test against, such as limiting checks to only WCAG 2.1 Level AA standards.
How do I integrate Storybook a11y checks into my CI pipeline?
Import the runA11y function from @storybook/addon-a11y into your Jest or Playwright tests. Render your component, pass the container element to runA11y, and assert that the resulting violations array has zero length. This allows you to fail builds when accessibility violations are detected.
What is the difference between the a11y panel and programmatic testing?
The Accessibility panel provides visual feedback during development, displaying violations, passes, and incomplete checks directly in the Storybook UI. Programmatic testing using runA11y allows you to execute the same axe-core checks within automated test suites, returning raw results objects that you can assert against programmatically without opening the browser interface.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →