A Claude Code plugin that reviews AI-generated frontend code for accessibility issues, explains who is affected and how, and suggests practical fixes — without leaving your editor.
Claude Code · WCAG 2.1 AA · Static Analysis
AI coding tools (Cursor, Copilot, Claude Code) generate components in seconds. Accessibility does not come included by default.
These tools routinely produce the same failures:
- Placeholder text used instead of label elements
- Icon-only controls with no accessible name
- Div-based buttons that cannot be reached by keyboard
- Inaccessible modal implementations with no role, focus management, or focus trap
- Excessive or invalid ARIA added without understanding its effect
- Skipped heading hierarchy that breaks screen reader navigation
- Missing keyboard support for interactive elements
Enterprise accessibility teams are often responsible for reviewing hundreds of components across many repositories with limited staffing. Issues discovered late — after development, after QA, after a legal complaint — are significantly more expensive to fix.
A11y-Check shifts accessibility review earlier into the development workflow.
On a personal note, I am partially hard of seeing. I rely on browser zoom, screen readers, and enlarged interfaces to use computers especially at night after removing scleral contact lenses. When a developer ships an inaccessible interface, it is not just a compliance problem for their company, it is a wall that prevents users from completing basic tasks.
This plugin is built from that lived experience. The goal is to make the gap between fast AI-generated code and accessible user experiences smaller.
- Enterprise Accessibility QA Engineers responsible for reviewing high component volume with limited staffing — use the agent to automate first-pass review so you can focus on complex usability and assistive technology testing
- Frontend developers building with AI tools who want inline accessibility guardrails while coding
- Teams that want to shift accessibility review earlier without adding a manual review bottleneck
What this plugin is not: It is not a replacement for professional accessibility review, manual screen reader testing (NVDA, JAWS, VoiceOver), or WCAG certification. The hard work of accessibility still requires human judgment. This handles the repetitive mechanical part.
claude agents run a11y-checkScans every .jsx, .tsx, .html, .vue, and .svelte file in the project across
8 accessibility categories. For each violation it explains the technical issue, who is
affected, and the exact minimal fix. Writes a persistent a11y-report.md to the project
root. Use this at the start of a review session, before a release, or after a sprint
of AI-assisted development.
/wcag-check src/components/LoginForm.tsx
Quick conversational check on a single file or pasted snippet. Responds in the chat and keeps the conversation going — no file is written. Use this while coding to get immediate feedback before finishing a component.
Two hooks work together to keep accessibility visible throughout development.
After Claude edits any frontend file, the first hook fires and Claude offers three
choices: check it now with /wcag-check, defer it with /a11y-todo add, or skip it.
If you defer, the issue is recorded in a11y-todos.md — a plain markdown file in your
project root that you can read and edit manually.
Before every git commit, the second hook surfaces any open todos as a last-call
reminder. If everything is resolved, you see a clean confirmation. If items are open,
they are listed so you can decide whether to fix them first or commit with known issues.
Neither hook blocks your workflow. No auto-fixing. Accessibility remediation stays in the developer's hands.
Both the agent and the slash command check these 8 categories:
| Category | What it checks |
|---|---|
| Semantic HTML | Div-based buttons, missing landmark regions |
| Keyboard accessibility | onClick without keyboard handler, broken tab order |
| Form accessibility | Placeholder-as-label, missing error associations |
| Screen reader support | Missing alt text, aria-hidden on focusable elements |
| Accessible naming | Icon-only controls, unnamed buttons and links |
| Heading structure | Skipped levels, multiple H1 elements |
| Modal accessibility | Missing role, aria-modal, focus management, focus trap |
| ARIA validation | Invalid or excessive ARIA usage |
- Claude Code CLI installed and authenticated
Verify:
claude --version - Node.js 18 or later (required for the hook script)
Verify:
node --version - A frontend project containing
.jsx,.tsx,.html,.vue, or.svelte files
Add the marketplace and install the plugin in two commands:
/plugin marketplace add Ab3y/a11y-check
/plugin install a11y-check@a11y-checkClaude Code will fetch the plugin, wire up the hooks, and register the agent and slash commands automatically. To get updates when a new version ships:
/plugin marketplace update a11y-checkStep 1 — Clone this repo
git clone https://github.com/Ab3y/a11y-check.gitStep 2 — Copy the plugin into your project
Mac / Linux:
cp -r a11y-check/.claude /path/to/your-project/.claudeWindows (PowerShell):
Copy-Item -Recurse a11y-check\.claude your-project\.claudeThe .claude/ folder contains the agent, slash command, hook script, and settings.
No npm install is required.
Step 3 — Verify the install
cd your-project
claude agents listYou should see a11y-check in the list.
Run a full project audit:
claude agents run a11y-checkThis scans every frontend file and writes a11y-report.md to your project root.
Check a single file inline:
/wcag-check src/components/LoginForm.tsx
Try the demo project:
cd demo
claude agents run a11y-checkThe demo/ folder contains intentional violations. You should see approximately
18–20 findings across 6 files.
a11y-report.md looks like this:
## Critical Findings (Level A — Must Fix)
**[LoginForm.tsx:28] WCAG 4.1.2 — Input has no accessible name**
Issue: <input type="email" placeholder="Email address" /> has no associated label,
no aria-label, and no aria-labelledby.
Impact: Screen reader users hear "Edit text" with no context about what information
this field expects. The placeholder disappears when they start typing, leaving
them with no label at all.
Fix: <label htmlFor="email">Email address</label>
<input id="email" type="email" placeholder="Email address" />a11y-report.md is a static code analysis report. It identifies issues visible
in the source code. It cannot check:
- Colour contrast ratios (requires computed CSS)
- Focus indicator visibility (requires rendered output)
- How a screen reader actually announces content (requires runtime testing)
Use this report as a first pass. Follow up with manual testing using NVDA, JAWS, or VoiceOver before a release. This is a tool to reduce repetitive review work, not to replace the accessibility review process.
https://www.loom.com/share/98476fd3e2e54417a19cbe27ed73362b
- To add a new accessibility check, extend the agent prompt in
.claude/agents/a11y-check.md - To build your own Claude Code plugin, follow the steps in CCPlugin_Guide.md
- Pull requests welcome — especially for Vue and Svelte-specific patterns and additional ARIA validation rules