npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@a11y-lens/cli

v0.4.1

Published

AI-powered semantic accessibility linter — reviews what static linters can't see. Runs on Claude Code, Codex, or Cursor at commit time.

Readme

a11y-lens

Package @a11y-lens/cli · CLI a11y-lens · Skill npx skills add jo-duchan/a11y-lens

AI-powered semantic accessibility linter. Reviews what static linters can't see — using the AI coding agent you already have (Claude Code, Codex, or Cursor).

Static linters check syntax: does this img have an alt? a11y-lens checks semantics: does this alt actually describe the image? Is this custom dropdown's keyboard interaction complete per the WAI-ARIA combobox pattern? Does the modal return focus to its trigger?

$ git commit -m "add plan selector"
a11y-lens: reviewing 1 file(s) with claude…

src/PlanSelect.jsx
  ✖ error:23  [aria-widgets] Custom dropdown is a div with onClick only — no combobox
     role, no aria-expanded, no listbox/option semantics. AT users get a plain text node.
     fix: use role="combobox" + aria-expanded + role="listbox"/"option", or a native <select>
  ✖ error:23  [keyboard-interaction] Dropdown cannot be operated by keyboard: no ArrowDown/
     ArrowUp/Enter/Escape handling per the APG combobox pattern.
     fix: add onKeyDown implementing the APG combobox key set

a11y-lens: 2 error(s), 0 warning(s) (reviewed by claude)
husky - pre-commit hook exited with code 1

How it works

  1. Collects the staged UI files (.jsx, .tsx, .html, .vue, .svelte, …) and their diffs.
  2. Sends them — together with a distilled rule set (skills/a11y-lens/references/*.md, drawn from WAI-ARIA APG, WCAG 2.2, eslint-plugin-jsx-a11y and axe-core coverage) — to a headless agent CLI: claude -p, codex exec, or cursor-agent -p, whichever is installed.
  3. Parses the structured findings and gates the commit on error severity. Warnings report but never block (unless --strict).

Infrastructure never blocks a commit. No agent CLI, no network, agent crash → a11y-lens warns and exits 0. Only real accessibility findings gate.

It samples; it does not audit

a11y-lens is an AI reviewer, not a deterministic linter. The same files reviewed twice can return different findings — even zero on a run that flagged issues a moment earlier. Read the output with that in mind:

  • A clean run ≠ zero issues. It means nothing surfaced in that sample, not that the code is fully accessible.
  • Findings don't converge to zero. Re-running to "clear" every last warning is the wrong mental model; a later run may raise something new.
  • The intended job is gating --staged diffs — catching problems as they're introduced. It is not a full-audit tool for an existing codebase; for that, pair it with a human accessibility review.

This is deliberate: only clear error-severity violations gate and warnings never block, precisely because AI output varies run to run. (This note belongs here, in the tool's own README — not in the AGENTS.md rules block that init injects into a consuming project, which is reserved for the accessibility rules themselves.)

Install

a11y-lens has two layers — install either or both:

Write time (agent skill). Teaches your coding agent the rules so UI code is accessible before the hook ever runs. The skills CLI installs it for Claude Code, Codex, Cursor, and 60+ other agents:

npx skills add jo-duchan/a11y-lens

Commit time (git hook gate):

npm install -D @a11y-lens/cli   # or pnpm add -D / yarn add -D
npx a11y-lens init

init installs the pre-commit hook for you — it detects lefthook (lefthook.yml), husky (.husky/), or plain .git/hooks, picks your package manager's runner (pnpm exec / yarn / bunx / npx), and adds the check idempotently. It also injects a rules reference into your AGENTS.md (a lightweight fallback for agents without skills support). Use --no-hook to skip hook installation.

Example (lefthook):

pre-commit:
  jobs:
    - name: a11y-lens
      run: npx a11y-lens check --staged

Usage

a11y-lens check --staged           # what the git hook runs
a11y-lens check src/Modal.tsx      # review specific files
a11y-lens check --staged --strict  # warnings also fail
a11y-lens check --staged --agent codex
a11y-lens rules                    # list rule categories

Escape hatches: A11Y_LENS_SKIP=1 git commit … or git commit --no-verify.

Rule set

One markdown file per category in skills/a11y-lens/references/, consumed by both the skill and the CLI. Each separates the static baseline (what eslint/axe already catch — not re-reported) from the semantic checks this tool exists for.

| Category | Semantic checks (examples) | |---|---| | 01-landmarks-headings | outline describes the document, not the visual design; one h1; labelled landmarks | | 02-images-alt | alt describes function in context; decorative silenced, informative never; icon-only controls named by action | | 03-forms-labels | placeholder ≠ label; errors tied via aria-describedby; accessible name matches visible label | | 04-aria-widgets | claimed APG patterns must be complete — half a combobox is worse than none; state in ARIA, not just CSS | | 05-keyboard-interaction | full APG key sets; no hover-only affordances; no keyboard traps | | 06-focus-management | overlays move focus in and return it; async results announced via live regions; SPA route changes handled |

Rules are plain markdown — tune them for your project by editing the files, no code changes needed.

Why commit-time AI review is cheap now

In AI-native workflows the entity blocked at pre-commit is usually an agent, not a human. A 10–30 second semantic review is a fine price when the committer can read the findings, fix them, and retry without getting annoyed.

Requirements

License

MIT © Duchan Jo — see NOTICE for rule-set attributions (eslint-plugin-jsx-a11y, axe-core, W3C WAI-ARIA APG, WCAG 2.2).