{"id":46063628,"url":"https://github.com/lukeslp/accessibility-devkit","last_synced_at":"2026-04-30T08:05:18.155Z","repository":{"id":342662604,"uuid":"1162108510","full_name":"lukeslp/accessibility-devkit","owner":"lukeslp","description":"Code-level tools for building accessible web applications — no overlays, no shortcuts","archived":false,"fork":false,"pushed_at":"2026-03-07T13:44:21.000Z","size":80,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-04-04T17:13:48.525Z","etag":null,"topics":["a11y","accessibility","devkit","toolkit","typescript","wcag"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/lukeslp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"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-02-19T22:01:47.000Z","updated_at":"2026-03-14T10:25:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lukeslp/accessibility-devkit","commit_stats":null,"previous_names":["lukeslp/accessibility-devkit"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/lukeslp/accessibility-devkit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukeslp%2Faccessibility-devkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukeslp%2Faccessibility-devkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukeslp%2Faccessibility-devkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukeslp%2Faccessibility-devkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lukeslp","download_url":"https://codeload.github.com/lukeslp/accessibility-devkit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukeslp%2Faccessibility-devkit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32458264,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T22:27:22.272Z","status":"online","status_checked_at":"2026-04-30T02:00:05.929Z","response_time":57,"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","devkit","toolkit","typescript","wcag"],"created_at":"2026-03-01T12:00:28.475Z","updated_at":"2026-04-30T08:05:18.086Z","avatar_url":"https://github.com/lukeslp.png","language":"TypeScript","funding_links":[],"categories":["Related Projects"],"sub_categories":[],"readme":"# accessibility-devkit\n\n[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)\n[![WCAG 2.2 AA](https://img.shields.io/badge/WCAG-2.2_AA-blue.svg)](https://www.w3.org/TR/WCAG22/)\n\nNot another overlay widget. Not a snippet pack. This is a collection of code-level tools, interaction patterns, and runtime utilities for building accessible applications from the ground up.\n\nAccessibility technical debt compounds fast. It's expensive to retrofit, and it locks real people out of what you built. Building it in from the start is easier than fixing it later — and it's the right thing to do.\n\nThree packages, all framework-agnostic TypeScript, all mapped to specific WCAG 2.x success criteria.\n\n---\n\n## Packages\n\n### [@accessibility-devkit/audit](./packages/audit)\n\nRuns axe-core accessibility audits and formats the results. Fits into CI pipelines, PR workflows, or one-off spot checks.\n\n- **axe-core runner** with configurable WCAG conformance level (A, AA, or AAA)\n- **Scoped audits** — include or exclude specific selectors to audit one section at a time\n- **Structured results** — violations come back with severity counts (critical, serious, moderate, minor), not just pass/fail\n- **Three report formats**: plain text for the console, markdown for docs and PRs, JSON for pipelines\n- **ESLint flat-config** for jsx-a11y — drop it into `eslint.config.js` and every JSX accessibility rule surfaces as a warning during development without blocking builds\n\n```ts\nimport { runAudit, formatReport } from '@accessibility-devkit/audit';\n\nconst result = await runAudit(document, { level: 'AA' });\nconsole.log(formatReport(result, 'markdown'));\nconsole.log(`${result.summary.critical} critical, ${result.summary.serious} serious`);\n\n// Audit a specific section, skip a noisy element\nconst scoped = await runAudit('#main-content', {\n  level: 'AAA',\n  exclude: ['#legacy-widget'],\n});\n```\n\n---\n\n### [@accessibility-devkit/components](./packages/components)\n\nAccessible UI primitives — the interaction patterns that are tedious to get right and painful to get wrong.\n\n- **FocusTrap** — confines keyboard focus to a container (modals, drawers, off-canvas panels). Supports initial focus targeting, pause/unpause for nested modals, and focus restoration on deactivation\n- **Roving Tabindex** — arrow key navigation within composite widgets (toolbars, tab lists, radio groups, menus). Tab exits the group. Handles wrap-around. Returns a cleanup function\n- **Screen Reader Announcements** — posts messages to an ARIA live region. Polite for status updates, assertive for errors. Creates the region once, reuses it\n- **Skip Link** — visually hidden, appears on keyboard focus, jumps past navigation to main content\n- **AccessibleDialog** — wraps `\u003cdialog\u003e` or `role=\"dialog\"` elements with focus trapping, ARIA attributes, and Escape-key dismissal\n- **AccessibleMenu** — disclosure-style dropdown: trigger gets `aria-haspopup` and `aria-expanded`, arrow keys navigate items, Escape closes, click-outside dismisses\n\n```ts\nimport { FocusTrap, createRovingTabindex, announceToScreenReader } from '@accessibility-devkit/components';\n\n// Trap focus in a modal\nconst trap = new FocusTrap(document.getElementById('modal')!);\ntrap.activate();\n\n// Arrow key navigation in a toolbar\nconst { destroy } = createRovingTabindex(toolbar, '[role=\"button\"]');\n\n// Tell screen readers what happened\nannounceToScreenReader('File saved');\nannounceToScreenReader('Session expired. Please sign in again.', 'assertive');\n```\n\n---\n\n### [@accessibility-devkit/accommodations](./packages/accommodations)\n\nColor perception, contrast math, and user preference detection.\n\n- **Color blindness simulation** — transforms any hex color as seen under 7 vision deficiency types: protanopia, deuteranopia, tritanopia (complete), protanomaly, deuteranomaly, tritanomaly (partial), and achromatopsia (full monochromacy)\n- **Contrast ratio calculation** — WCAG relative luminance math, returns a value between 1 (no contrast) and 21 (black on white)\n- **WCAG threshold checking** — pass/fail for AA or AAA on normal or large text (AA normal = 4.5:1, AA large = 3:1, AAA normal = 7:1, AAA large = 4.5:1)\n- **Automatic color adjustment** — give it a failing foreground/background pair and a target level, it darkens then lightens until it passes\n- **Preference detection** — `prefersReducedMotion()`, `prefersHighContrast()`, `prefersDarkMode()`, plus `watchPrefersReducedMotion()` which subscribes to live changes and returns an unsubscribe function\n\n```ts\nimport { meetsWCAG, findAccessibleColor, simulateColorBlindness } from '@accessibility-devkit/accommodations';\n\n// Check before shipping\nif (!meetsWCAG('#aaaaaa', '#ffffff')) {\n  const fixed = findAccessibleColor('#aaaaaa', '#ffffff');\n}\n\n// See how a color looks with deuteranopia\nconst simulated = simulateColorBlindness('#ff0000', 'deuteranopia');\n```\n\n---\n\n## Install\n\nInstall only what you need:\n\n```bash\nnpm install @accessibility-devkit/audit\nnpm install @accessibility-devkit/components\nnpm install @accessibility-devkit/accommodations\n```\n\nOr all three at once:\n\n```bash\nnpm install @accessibility-devkit/audit @accessibility-devkit/components @accessibility-devkit/accommodations\n```\n\nAll packages ship CJS and ESM builds with full TypeScript declarations.\n\n---\n\n## Development\n\n```bash\npnpm install\npnpm build       # Build all packages in parallel\npnpm lint        # Lint\npnpm test        # Run tests across all packages\npnpm changeset   # Create a changeset for versioning\npnpm release     # Build and publish\n```\n\n---\n\n## Related Projects\n\n| Project | What it does |\n|---------|-------------|\n| [accessibility-devkit-llm](https://github.com/lukeslp/accessibility-devkit-llm) | Language model extension — alt text generation, WCAG auditing with LLMs, MCP server, and agent skill definitions |\n| [awesome-accessibility](https://github.com/lukeslp/awesome-accessibility) | Curated list of accessibility resources and tools |\n| [accessibility-atlas](https://github.com/lukeslp/accessibility-atlas) | 53 datasets on disability demographics, web accessibility, and assistive technology usage |\n\n---\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md).\n\n---\n\n## Author\n\n**Luke Steuber** · [lukesteuber.com](https://lukesteuber.com) · [@lukesteuber.com](https://bsky.app/profile/lukesteuber.com)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukeslp%2Faccessibility-devkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flukeslp%2Faccessibility-devkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukeslp%2Faccessibility-devkit/lists"}