Package Exports
- a11y-commit-validator
- a11y-commit-validator/src/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 (a11y-commit-validator) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
a11y-commit-validator ♿
The accessibility guardian for your Git workflow.
Automatically scans staged HTML, JSX, JS and Liquid files for WCAG violations before every commit — powered by axe-core, eslint-plugin-jsx-a11y, and AI-powered fix suggestions (Groq, GitHub Models, or OpenAI — your choice).
✨ Features
- ♿ WCAG 2.0 / 2.1 / 2.2 Compliance — Full audit via axe-core for HTML files
- ⚛️ React / JSX Support — AST-level analysis with eslint-plugin-jsx-a11y
- 💧 Liquid Template Support — Regex-based rules for Shopify / Liquid files
- 🤖 AI-Powered Suggestions — 3 providers supported (Groq, GitHub Models, OpenAI). Works with whichever you have. Falls back to built-in suggestions if none configured
- 🔧 Auto-Fix Mode — Automatically patches fixable issues and re-stages them
- 🎨 Beautiful Terminal UI — Animated spinners, coloured output, progress bar
- 🛡️ Zero Config — Works out of the box, no
.eslintrcor config files needed - 🔌 Husky / pre-commit ready — Drop-in integration with any Git hook tool
What it does
Every time you run git commit, this tool:
- Detects which
.html,.jsx,.js, and.liquidfiles you've staged - Scans them for WCAG 2.1 / 2.2 accessibility violations using:
- axe-core (deep audit for HTML via jsdom)
- eslint-plugin-jsx-a11y (AST-level JSX/React analysis)
- Regex rules (custom patterns for Liquid + extra JSX checks)
- Explains every issue and suggests a fix (via AI or built-in rules)
- Blocks the commit if issues are found — and optionally auto-fixes them
🚀 Installation
# Install as a dev dependency (recommended)
npm install --save-dev a11y-commit-validator
# Or install globally
npm install -g a11y-commit-validator⚙️ Configuration
Step 1 — Create your .env file
Create a .env file in the root of your project and add one (or more) AI provider keys:
# ── Option A: Groq (RECOMMENDED — completely free, no credit card) ────────────
GROQ_API_KEY=gsk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# ── Option B: GitHub Models (requires a GitHub personal access token) ─────────
# GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# ── Option C: OpenAI (requires a paid OpenAI API key) ─────────────────────────
# OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxThat's it — just one line in
.envis all you need.
🤖 AI Providers — How the Cascade Works
The tool tries your configured providers in priority order. The first one that responds successfully is used. If none are available, it falls back to built-in suggestions automatically.
┌─────────────────────────────────────────────────────────────┐
│ AI Provider Cascade (auto-fallback) │
│ │
│ 1️⃣ GITHUB_TOKEN set? ──→ Try GitHub Models (gpt-4o) │
│ │ blocked / error │
│ ▼ │
│ 2️⃣ OPENAI_API_KEY set? ──→ Try OpenAI API │
│ │ error │
│ ▼ │
│ 3️⃣ GROQ_API_KEY set? ──→ Try Groq (LLaMA 3.3 70B) ✅ │
│ │ error │
│ ▼ │
│ 4️⃣ None configured ──→ Built-in rule suggestions │
└─────────────────────────────────────────────────────────────┘Provider Comparison
| Provider | Key name in .env |
Cost | Best for |
|---|---|---|---|
| Groq ⭐ | GROQ_API_KEY |
Free — console.groq.com | Everyone. No credit card, fast LLaMA 3.3 70B |
| GitHub Models | GITHUB_TOKEN |
Free with GitHub account | If your org allows GitHub Models API |
| OpenAI | OPENAI_API_KEY |
Paid — platform.openai.com | If you already have an OpenAI subscription |
We recommend Groq — it's completely free, no credit card, and uses LLaMA 3.3 70B which gives excellent WHY + FIX suggestions for accessibility.
Getting a free Groq API key (2 minutes)
- Go to console.groq.com
- Sign in with Google or GitHub — no credit card needed
- Click API Keys → Create API key
- Paste into your
.env:GROQ_API_KEY=gsk_...
Environment Variables Reference
| Variable | Provider | Description |
|---|---|---|
GROQ_API_KEY |
Groq (free) | LLaMA 3.3 70B — sign up at console.groq.com |
GITHUB_TOKEN |
GitHub Models | Personal access token from github.com/settings/tokens |
OPENAI_API_KEY |
OpenAI | API key from platform.openai.com/api-keys |
A11Y_GROQ_MODEL |
Groq only | Override default model (default: llama-3.3-70b-versatile) |
No key at all? The tool still works — built-in rule-based WHY + FIX suggestions are included for every rule.
⚙️ Setup
Option 1 — Husky (recommended)
npm install --save-dev husky
npx husky install
npx husky add .husky/pre-commit "npx validate-a11y"Or create .husky/pre-commit manually:
#!/usr/bin/env sh
. "$(dirname "$0")/_/husky.sh"
echo "Running accessibility check..."
npx validate-a11y || exit 1Make it executable (Mac/Linux): chmod +x .husky/pre-commit
Option 2 — Manual Git hook
#!/usr/bin/env sh
# .git/hooks/pre-commit
npx validate-a11y || exit 1chmod +x .git/hooks/pre-commitOption 3 — npm script only
{ "scripts": { "validate-a11y": "validate-a11y" } }🔄 Workflow
git add . ← Stage your files
│
▼
git commit -m "your message" ← Triggers the hook automatically
│
▼
♿ a11y-commit-validator runs
│
├── Detects staged .html / .jsx / .js / .liquid files
├── Scans each file for WCAG violations
├── Calls AI for WHY + FIX (Groq → GitHub Models → OpenAI → built-in fallback)
│
├── ✅ No issues? → Commit goes through
└── ❌ Issues found? → Commit BLOCKED
Auto-fix or fix manually
git add . && git commit again📋 Rules checked
24 custom rules — grouped by WCAG Success Criterion. All run on .liquid and .html. Rules marked ⚛️ also run on .jsx/.js (alongside the richer ESLint AST versions).
SC 1.1.1 — Non-text Content
| Rule ID | Severity | What it catches |
|---|---|---|
img-missing-alt ⚛️ |
🔴 Critical | <img> with no alt attribute |
img-empty-alt ⚛️ |
🔴 Critical | <img alt=""> on a meaningful image |
SC 1.2.2 — Captions (Prerecorded)
| Rule ID | Severity | What it catches |
|---|---|---|
video-missing-captions |
🔴 Critical | <video> with no <track kind="captions"> |
SC 1.3.1 — Info and Relationships
| Rule ID | Severity | What it catches |
|---|---|---|
table-missing-headers |
🟡 Warning | <table> with no <th> or scope attribute |
SC 1.4.1 — Use of Color
| Rule ID | Severity | What it catches |
|---|---|---|
link-underline-removed |
🟡 Warning | <a style="text-decoration:none"> — links relying on colour alone |
SC 1.4.2 — Audio Control
| Rule ID | Severity | What it catches |
|---|---|---|
autoplay-media |
🟡 Warning | <audio> or <video autoplay> |
SC 2.4.6 — Headings and Labels
| Rule ID | Severity | What it catches |
|---|---|---|
empty-heading ⚛️ |
🔴 Critical | <h1>–<h6> with no text content |
SC 2.4.7 — Focus Visible
| Rule ID | Severity | What it catches |
|---|---|---|
focus-outline-removed |
🔴 Critical | :focus { outline: none/0 } in style blocks |
inline-outline-removed |
🔴 Critical | style="outline:none" inline |
SC 3.3.2 — Labels or Instructions
| Rule ID | Severity | What it catches |
|---|---|---|
input-missing-label ⚛️ |
🔴 Critical | <input> with no aria-label or id |
select-missing-label ⚛️ |
🔴 Critical | <select> with no aria-label or id |
textarea-missing-label ⚛️ |
🔴 Critical | <textarea> with no aria-label or id |
SC 4.1.1 — Parsing
| Rule ID | Severity | What it catches |
|---|---|---|
duplicate-id |
🔴 Critical | Duplicate id attribute values in one file |
SC 4.1.2 — Name, Role, Value
| Rule ID | Severity | What it catches |
|---|---|---|
button-missing-label ⚛️ |
🔴 Critical | <button></button> with no accessible name |
anchor-missing-label ⚛️ |
🔴 Critical | <a></a> with no text or aria-label |
html-missing-lang ⚛️ |
🔴 Critical | <html> missing lang attribute |
custom-control-missing-label |
🔴 Critical | Element with interactive role= but no aria-label/aria-labelledby/title |
aria-hidden-focusable |
🔴 Critical | aria-hidden="true" on a focusable element (<a>, <button>, <input>, etc.) |
iframe-missing-title ⚛️ |
🔴 Critical | <iframe> with no title attribute |
General / Deprecated
| Rule ID | Severity | What it catches |
|---|---|---|
marquee-tag |
🔴 Critical | Deprecated <marquee> element |
blink-tag |
🔴 Critical | Deprecated <blink> element |
onclick-non-interactive |
🟡 Warning | onClick on a non-interactive <div> or <span> |
aria-expanded-static |
🔵 Info | aria-expanded hardcoded to "true"/"false" |
tabindex-positive |
🔵 Info | tabindex value greater than 0 |
Plus all axe-core WCAG 2.0 / 2.1 / 2.2 rules for .html files and all eslint-plugin-jsx-a11y recommended rules for .jsx / .js files — bringing the total coverage to 87 WCAG success criteria.
📂 Supported file types
| Extension | Scanner used |
|---|---|
.html |
axe-core via jsdom (full WCAG 2.2 audit) |
.jsx |
eslint-plugin-jsx-a11y + regex rules |
.js |
eslint-plugin-jsx-a11y + regex rules |
.liquid |
Regex rules |
🤖 AI-Powered Analysis
For each violation the AI provides:
- WHY — One sentence explaining exactly how this harms disabled users
- FIX — A corrected, ready-to-paste snippet specific to your actual code
The analysis is powered by whichever provider you configure — the tool picks the first available one automatically.
�️ See it in action
Drop it in, stage your files, and commit. This is what you'll see:
① Startup & file detection
┌──────────────────────────────────────────────────────────┐
│ ♿ A11Y COMMIT VALIDATOR v2.0.2 │
│ 🤖 Powered by Groq AI │
└──────────────────────────────────────────────────────────┘
✔ Found 2 file(s) to scan
📄 src/components/ProductCard.jsx
📄 src/sections/Hero.jsx② Live scan with progress bar
Scanning files:
[01/02] ████████████████░░░░░░░░░░░░░░ 53% ProductCard.jsx
[02/02] ██████████████████████████████ 100% Hero.jsx
✖ Scan complete — 3 issue(s) found! (1 duplicate removed)③ AI steps in (whichever provider is configured — Groq shown here)
🤖 Groq AI analysis complete.④ Red alert — issues detected
////////////////////////////////////////////////////////////////
// ♿ ACCESSIBILITY ISSUES DETECTED //
////////////////////////////////////////////////////////////////
Summary: 🔴 2 Critical 🟡 1 Warning 🔵 0 Info (3 total)
🔧 3 auto-fixable (AI-enhanced)⑤ Per-issue breakdown
──────────────────────────────────────────────────────────
[01] 🔴 CRITICAL jsx-a11y/alt-text Line 9
src/components/ProductCard.jsx
Why Images without alt text are completely invisible to screen
readers, locking out millions of visually impaired users.
Fix <img src={product.image} alt={product.title} className="card__img" />
[02] 🔴 CRITICAL jsx-a11y/click-events-have-key-events Line 18
src/components/ProductCard.jsx
Why A click-only handler locks out keyboard and switch-device
users who cannot use a mouse — WCAG 2.1 failure.
Fix <div role="button" tabIndex={0} onClick={...} onKeyDown={...}>
[03] 🟡 WARNING jsx-a11y/label-has-associated-control Line 34
src/sections/Hero.jsx
Why A form input with no associated label is unreadable by screen
readers — users won't know what the field is for.
Fix <label htmlFor="email">Email address</label>
<input id="email" type="email" />
──────────────────────────────────────────────────────────⑥ Interactive auto-fix prompt
╔══════════════════════════════╗
║ 🔧 AUTO-FIX AVAILABLE ║
╚══════════════════════════════╝
Groq AI has suggested fixes for 3 of the 3 issue(s) found.
What would you like to do?
[1] ✅ Apply all fixes automatically
[2] 🔍 Review & apply fixes one by one
[3] ⏭️ Skip — I'll fix them manually
Enter choice (1-3): 1
✅ Applied 3/3 fix(es) and re-staged the affected file(s).⑦ All clean
✅ ALL ACCESSIBILITY CHECKS PASSED!
All validators passed! Committing...🔧 Troubleshooting
No staged files detected
Run
git add <file>before committing. Only staged files are scanned.
SSL certificate error (corporate networks)
npm error UNABLE_TO_GET_ISSUER_CERT_LOCALLYRun once:
npm config set strict-ssl false
Groq API unavailable
Falls back to built-in suggestions automatically. No action needed.
🔌 Programmatic API
const { run } = require('a11y-commit-validator');
await run();const { scanFile } = require('a11y-commit-validator/src/scanner');
const issues = await scanFile('src/index.html');
// [{ file, ruleId, description, match, lineNumber, wcag }]// Enhance issues with AI suggestions (uses whichever provider key is in .env)
const { enhanceWithCopilot } = require('a11y-commit-validator/src/copilot');
const enhanced = await enhanceWithCopilot(issues);
// [{ ...issue, copilotWhy, copilotFix }] — Groq / GitHub Models / OpenAI / built-inconst { applyAllFixes } = require('a11y-commit-validator/src/fixer');
const { applied, failed, total } = applyAllFixes(enhanced);🆕 What's new in v2.0.0
- 🤖 Groq AI integration — Free LLaMA 3.3 70B, no credit card needed
- Auto-fix engine — Apply AI-suggested fixes from the terminal, files re-staged automatically
- 🎨 Simplified terminal output — Cleaner, focused issue display
- 🐛 Fixed duplicate output bug — HOW TO FIX section prints exactly once
- 🔒 Safer AI fixes — Constrained to single-line changes, prevents broken JSX
📈 Roadmap
- VS Code extension integration
- Support for Vue
.vuesingle-file components - WCAG 3.0 rules (when finalised)
- Custom rule configuration via
.a11yrc.json - GitHub Actions / CI mode
- Support for
.svelteand.astrofiles
🤝 Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit:
git commit -m "Add my feature" - Push and open a Pull Request
📋 Requirements
- Node.js: >= 16.0.0
- Git: Any recent version
- AI Provider: Optional — add one key to
.env. Groq is free (console.groq.com). GitHub Models and OpenAI also supported. Falls back to built-in suggestions if none configured
🙏 Acknowledgments
- axe-core — The gold standard for accessibility auditing
- eslint-plugin-jsx-a11y — AST-level JSX rules
- Groq — Free, blazing-fast LLaMA inference
- The open-source accessibility community
📜 License
MIT
♿ Stop shipping inaccessible code. Catch it before it reaches your users.
Because accessibility isn't a nice-to-have — it's the baseline every developer owes the world.
Built with ❤️ by Rohit Sarkar
Every commit counts. Make it accessible.