JSPM

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

Pre-commit accessibility validator for HTML, JSX, JS and Liquid files. Blocks commits with WCAG violations and provides GitHub Copilot-powered fix suggestions.

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).

npm version License: MIT Node.js WCAG 2.2


✨ 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 .eslintrc or 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:

  1. Detects which .html, .jsx, .js, and .liquid files you've staged
  2. 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)
  3. Explains every issue and suggests a fix (via AI or built-in rules)
  4. 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-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

That's it — just one line in .env is 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 Freeconsole.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)

  1. Go to console.groq.com
  2. Sign in with Google or GitHub — no credit card needed
  3. Click API KeysCreate API key
  4. 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

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 1

Make 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 1
chmod +x .git/hooks/pre-commit

Option 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_LOCALLY

Run 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-in
const { 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 .vue single-file components
  • WCAG 3.0 rules (when finalised)
  • Custom rule configuration via .a11yrc.json
  • GitHub Actions / CI mode
  • Support for .svelte and .astro files

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Commit: git commit -m "Add my feature"
  4. 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.