{"id":50941610,"url":"https://github.com/aks-builds/a11y-delta","last_synced_at":"2026-06-17T15:30:53.124Z","repository":{"id":364297945,"uuid":"1267291550","full_name":"aks-builds/a11y-delta","owner":"aks-builds","description":"Accessibility audit delta — catch only new axe violations, powered by Playwright","archived":false,"fork":false,"pushed_at":"2026-06-12T13:10:26.000Z","size":37,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-12T14:11:56.717Z","etag":null,"topics":["a11y","accessibility","accessibility-testing","axe-core","ci","cli","devtools","eaa","nodejs","playwright","wcag"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aks-builds.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-12T12:02:14.000Z","updated_at":"2026-06-12T13:10:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/aks-builds/a11y-delta","commit_stats":null,"previous_names":["aks-builds/a11y-delta"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/aks-builds/a11y-delta","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aks-builds%2Fa11y-delta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aks-builds%2Fa11y-delta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aks-builds%2Fa11y-delta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aks-builds%2Fa11y-delta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aks-builds","download_url":"https://codeload.github.com/aks-builds/a11y-delta/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aks-builds%2Fa11y-delta/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34453440,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-17T02:00:05.408Z","response_time":127,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["a11y","accessibility","accessibility-testing","axe-core","ci","cli","devtools","eaa","nodejs","playwright","wcag"],"created_at":"2026-06-17T15:30:52.448Z","updated_at":"2026-06-17T15:30:53.112Z","avatar_url":"https://github.com/aks-builds.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# ♿ a11y-delta\n\n**Gate PRs on new accessibility violations — not on ones you already know about.**\n\n`a11y-delta` runs axe-core audits via Playwright on a baseline and a candidate, diffs the results,\nand reports **only the violations your PR introduced**. Pre-existing debt never blocks the gate.\n\n[![CI](https://github.com/aks-builds/a11y-delta/actions/workflows/ci.yml/badge.svg)](https://github.com/aks-builds/a11y-delta/actions/workflows/ci.yml)\n[![CodeQL](https://github.com/aks-builds/a11y-delta/actions/workflows/codeql.yml/badge.svg)](https://github.com/aks-builds/a11y-delta/actions/workflows/codeql.yml)\n[![npm version](https://img.shields.io/npm/v/a11y-delta.svg)](https://www.npmjs.com/package/a11y-delta)\n[![License MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n\u003c/div\u003e\n\n---\n\n## The problem it solves\n\n```javascript\n// Every team that tries to gate accessibility in CI hits the same wall:\n// @axe-core/cli exits 1 if ANY violation exists.\n// If you already have 47 old issues your gate is always red.\n// Teams disable it. Nothing improves.\n\n// a11y-delta only flags violations your PR introduced:\n//   baseline: 47 violations  →  candidate: 48 violations  →  exit 1 (1 new)\n//   baseline: 47 violations  →  candidate: 47 violations  →  exit 0 (none new)\n```\n\n---\n\n## Prerequisites\n\nPlaywright requires a Chromium binary. Install once per machine or CI environment:\n\n```bash\nnpx playwright install chromium\n# On Linux CI runners also install system deps:\nnpx playwright install --with-deps chromium\n```\n\n---\n\n## Install\n\n```bash\n# Run directly with npx (no global install needed):\nnpx a11y-delta --baseline https://staging.example.com --candidate https://preview.example.com\n\n# Or install globally:\nnpm install -g a11y-delta\n```\n\n---\n\n## Usage\n\n### Compare two live URLs\n\n```bash\na11y-delta \\\n  --baseline  https://staging.example.com \\\n  --candidate https://preview.example.com\n```\n\n### Save a snapshot, then compare against it later\n\n```bash\n# Save the current production state as a baseline snapshot\na11y-delta \\\n  --baseline  https://example.com \\\n  --candidate https://example.com \\\n  --save baseline.json\n\n# On each PR, compare the preview against the saved baseline\na11y-delta \\\n  --baseline  baseline.json \\\n  --candidate https://preview-${{ github.event.pull_request.number }}.example.com\n```\n\n### GitHub Actions integration\n\n```yaml\n- name: Install Playwright browser\n  run: npx playwright install --with-deps chromium\n\n- name: Accessibility delta check\n  id: a11y\n  run: |\n    npx a11y-delta \\\n      --baseline  https://staging.example.com \\\n      --candidate https://preview-${{ github.event.pull_request.number }}.example.com \\\n      --format github-comment \u003e a11y-comment.md || true\n    cat a11y-comment.md \u003e\u003e $GITHUB_STEP_SUMMARY\n\n- name: Post result as PR comment\n  if: github.event_name == 'pull_request'\n  run: gh pr comment ${{ github.event.pull_request.number }} --body-file a11y-comment.md\n  env:\n    GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n- name: Fail if new violations found\n  run: |\n    npx a11y-delta \\\n      --baseline  https://staging.example.com \\\n      --candidate https://preview-${{ github.event.pull_request.number }}.example.com\n```\n\n---\n\n## Options\n\n| Flag | Default | Description |\n|---|---|---|\n| `--baseline, -b` | required | URL or saved snapshot JSON |\n| `--candidate, -c` | required | URL or saved snapshot JSON |\n| `--fail-on` | `critical,serious` | Comma-separated impact levels that exit 1 |\n| `--save` | — | Write candidate audit as JSON for future use as baseline |\n| `--format, -f` | `table` | `table` \\| `github-comment` \\| `json` |\n| `--timeout` | `30000` | Playwright navigation timeout (ms) |\n| `--viewport` | `1280x800` | Browser viewport |\n| `--wait-for` | — | CSS selector to wait for before running the audit |\n| `--header` | — | HTTP header for Playwright requests (repeatable) |\n\n### Impact levels (most → least severe)\n\n`critical` → `serious` → `moderate` → `minor`\n\n`--fail-on critical,serious` exits 1 for critical and serious new violations.  \n`--fail-on minor` exits 1 for any new violation at any impact level.\n\n---\n\n## How violation identity works\n\nTwo audits can have the same axe rule firing on different elements, or the same element appearing in both. `a11y-delta` identifies each occurrence as `ruleId::N:selector` (where N is the number of selectors in the target chain). A violation is \"new\" only if that exact rule+element combination wasn't present in the baseline.\n\nPartial fixes are reflected correctly: if you fix 3 of 5 failing elements for a rule, only the 2 remaining unfixed elements continue to appear as existing violations.\n\n---\n\n## License\n\nMIT © [aks-builds](https://github.com/aks-builds)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faks-builds%2Fa11y-delta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faks-builds%2Fa11y-delta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faks-builds%2Fa11y-delta/lists"}