JSPM

@barrierbreak/eslint-plugin-a11yinspect

1.0.13
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 92
  • Score
    100M100P100Q99001F
  • License MIT

ESLint plugin for comprehensive static accessibility analysis - 92 rules covering images, forms, ARIA, landmarks, tables, and semantic HTML

Package Exports

  • @barrierbreak/eslint-plugin-a11yinspect
  • @barrierbreak/eslint-plugin-a11yinspect/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@barrierbreak/eslint-plugin-a11yinspect) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

eslint-plugin-a11yinspect

ESLint plugin for comprehensive static accessibility analysis

npm version License: MIT

Static accessibility analysis for React/JSX with 89 rules covering Web Content Accessibility Guideline (WCAG) guidelines, EN 301 549 and other accessibility standards. Catch accessibility issues at development time with zero runtime overhead.

Features

  • 89 accessibility rules (split into error and warning variants) across 10 categories
  • ESLint 7, 8, 9 compatible - works with legacy and flat config
  • Pure static analysis - no browser, jsdom, or runtime required
  • Framework agnostic - React, Next.js, Vite, CRA
  • TypeScript ready - full support for .tsx files
  • Zero dependencies - lightweight and fast

Why Accessibility Matters at Development

Accessibility isn't just a feature—it's a responsibility. It ensures that people of all abilities can navigate, understand, and interact with digital products without barriers. Following accessibility best practices leads to more inclusive experiences, stronger usability, and more resilient code.

Standards like the Web Content Accessibility Guidelines (WCAG) provide a benchmark for making the web perceivable, operable, understandable, and robust for everyone. Incorporating these guidelines early in development helps teams build with inclusion at the core rather than treating accessibility as an afterthought.

A Great Place to Start: A11yInspect

The A11yInspect ESLint Plugin and A11yInspect Browser Extension make it easier to bring accessibility into your everyday development workflow.

A11yInspect ESLint Plugin catches potential accessibility issues right inside your code editor, helping you enforce WCAG-aligned patterns from the start.

The A11yInspect Browser Extension provides in-browser insights into real accessibility concerns, showing how issues appear in the actual user experience.

Together, these tools give developers a practical, approachable way to begin building accessible applications that align with modern standards like WCAG.

Installation

npm install @barrierbreak/eslint-plugin-a11yinspect --save-dev

Quick Start

Create eslint.config.mjs and copy-paste:

// eslint.config.mjs
import a11yinspect from "@barrierbreak/eslint-plugin-a11yinspect";

export default [
  {
    files: ["**/*.{js,jsx,ts,tsx}"],
    languageOptions: {
      ecmaVersion: "latest",
      sourceType: "module",
      parserOptions: {
        ecmaFeatures: { jsx: true }
      }
    },
    plugins: { a11yinspect },
    rules: {
      ...a11yinspect.configs.recommended.rules
    }
  }
];

That's it — all 89 rules are enabled with appropriate severity levels (error or warn).

ESLint 7-8 (.eslintrc)

Add to your .eslintrc.json:

{
  "extends": ["plugin:@barrierbreak/a11yinspect/recommended"]
}

This enables all 89 accessibility rules with appropriate severity levels (error rules as error, warning rules as warn).

Available Configs

Config Description
recommended -error rules as error, -warning rules as warn (default, start here)
strict All 89 rules set to error — blocks CI on any issue
errors-only Only -error rules enabled, all -warning rules off
warnings-only Only -warning rules enabled (as warn), all -error rules off

ESLint 9+ (flat config):

// Use any config — just swap "recommended" for the one you want
rules: {
  ...a11yinspect.configs.recommended.rules   // or .strict, ["errors-only"], ["warnings-only"]
}

ESLint 7-8 (.eslintrc):

{
  "extends": ["plugin:@barrierbreak/a11yinspect/recommended"]
}

Replace recommended with strict, errors-only, or warnings-only as needed.

Accessibility Rules Overview

89 rules organized by category (split into error and warning variants):

Images & Media

Rule Default Description
img-element-error error Alt text missing, generic alt detection
img-element-warning warn Decorative images, alt text quality
svg-element-error error SVG roles, accessible names
svg-element-warning warn SVG missing role, accessible name, or generic description
media-element-error error Audio/video critical accessibility
media-element-warning warn Audio/video recommendations
track-element-error error Subtitle/caption tracks
canvas-element-error error Canvas role, descriptions
canvas-element-warning warn Canvas decorative marking
Rule Default Description
a-element-error error Link text, href, accessible names
a-element-warning warn Link text quality
skip-link-warning warn Skip navigation links

Buttons & Interactive

Rule Default Description
button-element-error error Button types, text content
button-element-warning warn Button accessibility improvements
click-handler-warning warn Click handlers on non-interactive elements
focus-element-error error Focus management critical issues
focus-element-warning warn Focus management recommendations
slider-element-warning warn Slider role, accessible name, keyboard support

Forms

Rule Default Description
input-element-error error Input types and attributes
input-element-warning warn Input accessibility improvements
label-element-error error Label associations
label-element-warning warn Label for-attribute cross-reference (placeholder)
select-element-error error Select missing label, name attribute, or options
textarea-element-error error Textarea elements
textarea-element-warning warn Textarea improvements
form-element-error error Form structure critical issues
form-element-warning warn Form structure recommendations
optgroup-element-error error Option groups
autocomplete-element-error error Autocomplete attributes
autocomplete-element-warning warn Autocomplete recommendations
required-element-warning warn Required field visual indicator
area-element-error error Image map areas

Document Structure

Rule Default Description
heading-element-error error Empty headings, heading hierarchy, nested headings
heading-element-warning warn Heading improvements
lang-element-error error Language attributes
title-element-error error Page title
iframe-element-error error Iframe titles, hidden iframes
iframe-element-warning warn Iframe improvements
list-element-error error List structure critical issues
list-element-warning warn List improvements
dl-element-error error Definition lists
duplicate-id-error error Duplicate id attributes

ARIA

Rule Default Description
aria-element-error error ARIA attributes, roles critical issues
aria-element-warning warn ARIA recommendations
role-props-element-error error Role required/supported aria properties
role-props-element-warning warn Role property recommendations
description-element-error error aria-describedby critical issues
description-element-warning warn Description recommendations
expanded-element-warning warn aria-expanded states
disabled-element-warning warn aria-disabled
checked-element-error error aria-checked critical issues
checked-element-warning warn aria-checked recommendations
selected-element-warning warn aria-selected states
pressed-element-warning warn aria-pressed states
live-region-error error aria-live regions
orientation-element-error error Invalid aria-orientation values
accesskey-element-error error Accesskey critical issues
autofocus-element-warning warn Avoid autoFocus attribute

Landmarks

Rule Default Description
landmark-element-error error Missing main landmark
landmark-element-warning warn Landmark recommendations
section-element-warning warn Section elements
meta-element-error error Viewport zoom critical issues
meta-element-warning warn Meta recommendations

Tables

Rule Default Description
table-element-error error Headers, captions critical issues
table-element-warning warn Table recommendations
scope-element-error error Table header scope

Dialogs & Components

Rule Default Description
dialog-element-error error Dialog/alertdialog role or element missing accessible name
dialog-element-warning warn Dialog recommendations
details-element-error error Details/summary elements
details-element-warning warn Details element with aria-hidden
menu-element-error error menuitemradio/menuitemcheckbox accessible name, aria-checked; menubar accessible name
menu-element-warning warn Menu accessible names and structure
tab-element-warning warn Tab, tablist, tabpanel roles
distracting-element-error error No marquee/blink elements

Semantic HTML

Rule Default Description
figure-element-error error Figure/figcaption
abbr-element-error error Abbreviations
time-element-error error Time elements
blockquote-element-warning warn Blockquote citations
ruby-element-error error Ruby annotations
ruby-element-warning warn Ruby recommendations
hr-element-warning warn Horizontal rules
meter-element-error error Meter elements
progress-element-error error Progress elements
output-element-error error Output elements
object-element-error error Object missing type attribute or fallback content
object-element-warning warn Object element with aria-hidden
embed-element-error error Embedded content
map-element-error error Image maps
map-element-warning warn Map element with aria-hidden

Accessibility Examples

Bad Accessibility (will trigger errors)

// img missing alt and no aria alternative
<img src="logo.png" />

// Generic alt text
<img src="logo.png" alt="image" />

// Canvas missing role="img"
<canvas width="200" height="200"></canvas>

// Slider missing accessible name
<div role="slider"></div>

// Empty heading
<h1></h1>

// Nested heading
<h2><h3>Nested</h3></h2>

// List with no items
<ul></ul>

// Table missing headers
<table><tr><td>Data</td></tr></table>

// iframe with empty title
<iframe src="/page" title="" />

// Viewport disables zoom
<meta name="viewport" content="user-scalable=no" />

Good Accessibility (passes checks)

// Proper alt text
<img src="logo.png" alt="Company Logo" />

// Canvas with role and description
<canvas role="img" aria-label="Sales chart for Q4">
  Fallback text
</canvas>

// Slider with name and keyboard support
<div role="slider" aria-label="Volume" tabIndex={0}></div>

// Heading with content
<h1>Welcome to Our Site</h1>

// Proper list structure
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
</ul>

// Table with headers and caption
<table>
  <caption>Sales Data</caption>
  <tr><th>Product</th><th>Sales</th></tr>
  <tr><td>Widget</td><td>100</td></tr>
</table>

// iframe with title
<iframe src="/page" title="Contact Form" />

// Accessible viewport
<meta name="viewport" content="width=device-width, initial-scale=1" />

// Button with accessible name
<button type="submit">Submit Form</button>

// Input with label
<label htmlFor="email">Email Address</label>
<input id="email" type="email" required />

// SVG with accessible name
<svg aria-label="Close icon" role="img">
  <path d="M10 10L20 20M20 10L10 20" stroke="currentColor" />
</svg>

// Link with descriptive text
<a href="/about" aria-label="Read more about our company">About Us</a>

// Proper language attribute
<html lang="en">

More Bad Accessibility Examples

// SVG without accessible name
<svg>
  <path d="M10 10L20 20" />
</svg>

// Button without accessible name
<button type="submit"></button>

// Click handler on non-interactive element
<div onClick={handleClick}>Click me</div>

// Input without label association
<input type="email" placeholder="Email" />

// Missing lang attribute
<html>
  <head>...</head>
</html>

// Duplicate id attributes
<div id="unique">Content 1</div>
<div id="unique">Content 2</div>

// Invalid aria attribute
<button aria-invalid="yes">Submit</button>

// Dialog without aria-modal
<dialog>Modal content</dialog>

// Marquee element (deprecated and distracting)
<marquee>Important announcement</marquee>

// Missing required aria attribute for role
<div role="checkbox" aria-checked="true"></div>

More Good Accessibility Examples

// SVG with proper accessibility
<svg aria-labelledby="title desc" role="img">
  <title id="title">Search Icon</title>
  <desc id="desc">A magnifying glass icon</desc>
  <circle cx="11" cy="11" r="8" />
</svg>

// Interactive button with proper attributes
<button type="button" aria-pressed={isPressed} onClick={toggle}>
  {isPressed ? 'Active' : 'Inactive'}
</button>

// Accessible click handler
<button onClick={handleClick} aria-label="Close dialog">X</button>

// Properly labeled input
<label>
  Email Address
  <input type="email" required aria-describedby="email-help" />
</label>
<span id="email-help">Enter your work email</span>

// Page with language
<html lang="en">
  <head><title>Page Title</title></head>
  <body>...</body>
</html>

// Valid aria attribute values
<button aria-invalid="true">Submit</button>

// Accessible dialog
<dialog aria-modal="true" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Confirm Action</h2>
  <p>Are you sure?</p>
</dialog>

// Proper checkbox role with all required attributes
<div role="checkbox" aria-checked={checked} tabIndex={0} onClick={toggle}>
  {checked ? 'Checked' : 'Unchecked'}
</div>

// Semantic figure with figcaption
<figure>
  <img src="chart.png" alt="Revenue growth chart" />
  <figcaption>Figure 1: Revenue growth in Q4 2024</figcaption>
</figure>

// Proper heading hierarchy
<h1>Main Title</h1>
<section>
  <h2>Section Title</h2>
  <h3>Subsection Title</h3>
</section>
<h2>Another Section</h2>

Accessibility Support for File Types

Extension Support
.js JavaScript
.jsx React JSX
.ts TypeScript (with @typescript-eslint/parser)
.tsx TypeScript JSX
.mjs ES Modules
.cjs CommonJS

This plugin checks JSX/TSX files only. For other template formats, see:

Framework Setup

Next.js

// eslint.config.mjs
import a11yinspect from "@barrierbreak/eslint-plugin-a11yinspect";

export default [
  {
    files: ["**/*.{js,jsx,ts,tsx}"],
    languageOptions: {
      parserOptions: { ecmaFeatures: { jsx: true } }
    },
    plugins: { a11yinspect },
    rules: {
      ...a11yinspect.configs.recommended.rules
    }
  },
  { ignores: [".next/**", "out/**"] }
];

Vite / CRA

// eslint.config.mjs
import a11yinspect from "@barrierbreak/eslint-plugin-a11yinspect";

export default [
  {
    files: ["src/**/*.{js,jsx,ts,tsx}"],
    languageOptions: {
      parserOptions: { ecmaFeatures: { jsx: true } }
    },
    plugins: { a11yinspect },
    rules: {
      ...a11yinspect.configs.recommended.rules
    }
  }
];

TypeScript

// eslint.config.mjs
import a11yinspect from "@barrierbreak/eslint-plugin-a11yinspect";
import tsParser from "@typescript-eslint/parser";

export default [
  {
    files: ["**/*.{ts,tsx}"],
    languageOptions: {
      parser: tsParser,
      parserOptions: { project: "./tsconfig.json" }
    },
    plugins: { a11yinspect },
    rules: {
      ...a11yinspect.configs.recommended.rules
    }
  }
];

CI/CD Integration

GitHub Actions

name: Accessibility Lint
on: [push, pull_request]
jobs:
  a11y-lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 18
      - run: npm ci
      - run: npx eslint . --format json --output-file a11y-report.json

package.json Scripts

{
  "scripts": {
    "lint": "eslint .",
    "lint:a11y": "eslint . --rule '{\"a11yinspect/img-element-error\": \"error\"}'",
    "lint:report": "eslint . --format json --output-file a11y-report.json"
  }
}

Troubleshooting eslint-plugin-a11yinspect

"Cannot find module 'eslint-plugin-a11yinspect'"

Make sure the plugin is installed in the project where ESLint is running:

npm install @barrierbreak/eslint-plugin-a11yinspect --save-dev

ESLint not recognizing JSX

Ensure JSX parsing is enabled:

parserOptions: {
  ecmaFeatures: { jsx: true }
}

Too many errors?

Start with critical rules only and gradually enable more:

rules: {
  "a11yinspect/img-element-error": "error",
  "a11yinspect/a-element-error": "error",
  "a11yinspect/heading-element-error": "error"
}

License

MIT - BarrierBreak

Resources