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:

  1. Runner (a11yRunner.ts) – Executes axe-core tests against the rendered story
  2. Utilities (a11yRunnerUtils.ts) – Formats results and filters violations
  3. Integration layer – Registers the addon with Storybook's manager UI and exposes the runA11y API

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-a11y and register it in .storybook/main.js to enable automated accessibility testing
  • Configure global axe-core rules in .storybook/preview.js using the parameters.a11y object
  • Apply the withA11y decorator 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 runA11y function 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →