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

@devframes/plugin-a11y

v0.7.3

Published

Devframe a11y inspector — runs axe-core against the host app, surfaces the violations through a Solid panel, and highlights the offending element in the page on hover. Works in dev (WebSocket) and static build modes.

Readme

@devframes/plugin-a11y

[!WARNING] Experimental This plugin is experimental and may change without a major version bump until it stabilizes.

An accessibility inspector built on devframe. It runs axe-core against a host application, lists the WCAG A/AA violations in a Solid panel, and highlights the offending element in the page when you hover a warning.

The scan + highlight loop works the same whether the plugin runs as a live dev server or as a baked static build.

How it works

Three pieces, two of them browser-side:

| Piece | Runs in | Role | |-------|---------|------| | Agent (src/inject) | the host app's page | runs axe-core, broadcasts the report, draws the highlight ring | | Panel (src/spa) | the devtools iframe | Solid SPA: lists violations, fires highlight/clear on hover | | Node (src/index.ts, src/node, src/rpc) | the devframe backend | get-config RPC (impact taxonomy) — live in dev, baked in a static build |

The agent and panel talk over a same-origin BroadcastChannel, not the devframe RPC backend. That is what keeps the live loop working in both modes: neither half needs a server to reach the other, only a shared browser origin (host page + panel iframe). devframe RPC carries the data model on top — get-config is a static function, so it resolves over WebSocket in dev and from the baked dump in a static build.

devframe deliberately provides no access to the host application's DOM, so the agent is the author-provided bridge into the page being checked. In a hub, the agent is the a11y dock's client script: attach a11yAgentBundlePath as the dock's clientScript (resolved to an importable URL — /@fs/… under Vite, or a statically-served path) and the hub's client runtime (createDevframeClientHost from @devframes/hub/client) imports it into the host page and calls its default export with the client-script context. Booted that way, the agent also mirrors each scan into the hub's messages feed — a summary entry driven through the loading → idle lifecycle plus one entry per violated rule, carrying the impact-mapped level, WCAG tags as labels, and the first offending element's selector and bounding box (rendered by @devframes/plugin-messages when the hub mounts it). Both minimal hub examples do exactly this. Outside a hub, one <script type="module"> for the same bundle does the job — the demo below shows it (no hub context, so the feed mirror simply stays off).

Run the demo

The demo serves an intentionally-broken host page and the panel from one origin so they share the channel.

pnpm -C plugins/a11y build       # build the panel + the agent bundle
pnpm -C plugins/a11y demo        # dev: live WebSocket RPC → http://localhost:4477/

pnpm -C plugins/a11y cli:build   # bake the static deploy (dist/static)
pnpm -C plugins/a11y demo:build  # static: baked RPC dump, no server

Open the URL, then hover any row in the panel — the matching element in the page gets a focus ring (and scrolls into view if it's off-screen). Both demo modes behave identically; the panel's websocket / static tag is the only tell.

Standalone, without a host app:

pnpm -C plugins/a11y dev         # panel only, at /__devframe-a11y-inspector/

File map

| Path | Export | Purpose | |------|--------|---------| | src/index.ts | . | createA11yDevframe() + the default DevframeDefinition; a11yAgentBundlePath — the agent module a hub attaches as this dock's client script | | src/node/index.ts | /node | setupA11y(ctx) — registers the RPC functions | | src/cli.ts | /cli | createA11yCli() — backs the devframe-a11y-inspector bin | | src/vite.ts | /vite | a11yVitePlugin() — mounts the panel into a Vite host | | src/client/index.ts | /client | connectA11y() — typed browser RPC client wrapper | | src/rpc/ | — | get-config static RPC + the type-safe client registry | | src/shared/protocol.ts | — | the agent ↔ panel BroadcastChannel contract | | src/inject/ | — | the host-page agent (axe scan, highlight overlay, hub messages mirror) → dist/inject/inject.js | | src/spa/ | — | the Solid panel SPA → dist/spa | | demo/ | — | same-origin host page + server (dev + static modes) | | tests/ | — | dev-server RPC + static-build dump |