npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@accesslint/storybook-addon

v0.8.10

Published

Catch accessibility violations in your Storybook stories as you develop

Readme

npm version license

@accesslint/storybook-addon

Catch accessibility violations in your Storybook stories as you develop. Powered by @accesslint/core.

Getting Started

npm install @accesslint/storybook-addon

Add the addon to your .storybook/main.ts (or .storybook/main.js):

const config = {
  addons: ["@accesslint/storybook-addon"],
};

export default config;

Restart Storybook and an AccessLint panel will appear in the addon bar. Every story is audited automatically after it renders.

Expand any violation to see the failing element, WCAG criteria, and remediation guidance. Click Highlight to outline the element in the preview.

Vitest integration

If you use @storybook/addon-vitest, add the AccessLint plugin next to storybookTest() in your Vite config:

import { accesslintTest } from "@accesslint/storybook-addon/vitest-plugin";

// Inside your Storybook test project:
plugins: [
  storybookTest({ configDir: ".storybook" }),
  accesslintTest(),
],

This gives you:

  • Per-story status dots in the sidebar (green/yellow/red)
  • A test widget in the sidebar's testing module
  • The toBeAccessible() matcher registered automatically
  • Accessibility results in CI alongside your component tests

Accessibility assertions

Use toBeAccessible() to make accessibility a first-class assertion in your tests and play functions.

With the Vitest plugin

If you added accesslintTest() above, the matcher is already registered. Use it directly in play functions:

import { expect } from "storybook/test";

export const Default = {
  play: async ({ canvasElement }) => {
    await expect(canvasElement).toBeAccessible();
  },
};

Without the Vitest plugin

For play functions or standalone tests without the plugin, import the matchers entry point to register toBeAccessible():

import "@accesslint/storybook-addon/matchers";

Then use it in a play function:

import { expect } from "storybook/test";
import "@accesslint/storybook-addon/matchers";

export const Default = {
  play: async ({ canvasElement }) => {
    await expect(canvasElement).toBeAccessible();
  },
};

Or in a standalone Vitest/Jest test:

import "@accesslint/storybook-addon/matchers";
import { render } from "@testing-library/react";

test("LoginForm is accessible", () => {
  const { container } = render(<LoginForm />);
  expect(container).toBeAccessible();
});

Disabling rules per assertion

await expect(canvasElement).toBeAccessible({
  disabledRules: ["accesslint-045"],
});

Failure output

When the assertion fails, the error message lists each violation with its rule ID, WCAG criteria, conformance level, message, and the CSS selector of the failing element:

Expected element to have no accessibility violations, but found 2:

  accesslint-001 [A] (1.1.1): Image is missing alt text
    img[src="hero.png"]

  accesslint-012 [A] (1.3.1): Form input is missing a label
    input[type="email"]

TypeScript support

Add the type reference to your tsconfig.json:

{
  "compilerOptions": {
    "types": ["@accesslint/storybook-addon/matchers"]
  }
}

Or add a triple-slash reference in a .d.ts file:

/// <reference types="@accesslint/storybook-addon/matchers" />

Configuration

Test mode

Control how violations are reported via parameters.accesslint:

// .storybook/preview.ts — applies to all stories
const preview = {
  parameters: {
    accesslint: {
      test: "todo", // "error" (default) | "todo" | "off"
    },
  },
};

export default preview;

| Mode | Behavior | | --- | --- | | "error" | Violations fail the test (default) | | "todo" | Violations show as warnings — yellow sidebar dots, non-blocking in CI | | "off" | Skip auditing entirely |

Override per-story:

export const Experimental = {
  parameters: {
    accesslint: { test: "off" },
  },
};

Disabling rules

Disable specific rules globally in your preview file:

// .storybook/preview.ts
import { configureRules } from "@accesslint/core";

configureRules({
  disabledRules: ["accesslint-045"], // e.g. disable landmark region rule
});

Skipping stories with tags

Tag individual stories or entire components with "skip-accesslint" to skip auditing:

// Skip a single story
export const Prototype = {
  tags: ["skip-accesslint"],
};

// Skip all stories for a component
export default {
  component: ExperimentalWidget,
  tags: ["skip-accesslint"],
};

With the Vitest plugin, you can also define custom skip tags:

accesslintTest({
  tags: { skip: ["skip-accesslint", "wip"] },
});

Portable stories

Use AccessLint with composeStories outside of Storybook (plain Vitest, Jest, or Playwright CT).

In your test setup file, pass the AccessLint annotations to setProjectAnnotations:

// vitest.setup.ts
import { setProjectAnnotations } from "@storybook/react";
import { enableAccessLint } from "@accesslint/storybook-addon/portable";
import * as previewAnnotations from "./.storybook/preview";

const project = setProjectAnnotations([
  previewAnnotations,
  enableAccessLint(),
]);

beforeAll(project.beforeAll);

Then in your tests:

import { composeStories } from "@storybook/react";
import * as stories from "./Button.stories";

const { Primary } = composeStories(stories);

test("Primary button is accessible", async () => {
  await Primary.run();
  // AccessLint afterEach runs automatically via the annotations
});

API reference

Exports

| Entry point | Description | | --- | --- | | @accesslint/storybook-addon | Main addon registration (manager + preview) | | @accesslint/storybook-addon/vitest-plugin | accesslintTest() Vite plugin for Vitest integration | | @accesslint/storybook-addon/vitest-setup | Setup file registered by the Vite plugin | | @accesslint/storybook-addon/matchers | toBeAccessible() custom matcher | | @accesslint/storybook-addon/portable | enableAccessLint() for portable stories | | @accesslint/storybook-addon/preview | Preview annotations (afterEach hook) |

accesslintTest(options?)

Vite plugin that registers AccessLint's afterEach annotation and the toBeAccessible() matcher for Vitest story tests.

| Option | Type | Description | | --- | --- | --- | | tags.skip | string[] | Stories with any of these tags will not be audited |

parameters.accesslint

| Parameter | Type | Default | Description | | --- | --- | --- | --- | | test | "todo" \| "error" \| "off" | "error" | Controls how violations are reported | | disable | boolean | false | Set to true to skip auditing (same as test: "off") |

toBeAccessible(options?)

Custom matcher for asserting an element has no accessibility violations.

| Option | Type | Description | | --- | --- | --- | | disabledRules | string[] | Rule IDs to skip for this assertion |

enableAccessLint()

Returns AccessLint's preview annotations for use with setProjectAnnotations in portable stories setups.

Compatibility

| Addon version | Storybook version | | ------------- | ----------------- | | 0.7.x | 10.x | | 0.6.x | 10.x |

Issues

Please report issues in the AccessLint core repository.

License

MIT