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

focuspath

v0.7.2

Published

See where keyboard navigation breaks. A visual accessibility scanner for focus order.

Readme

FocusPath

FocusPath traverses a web page with Chromium, records its keyboard focus sequence, flags deterministic problems, and writes a portable visual HTML report.

npx focuspath https://example.com

FocusPath complements manual accessibility testing and established rule engines; it is not a WCAG conformance test.

CLI

focuspath <url> [options]

-o, --output <file>          Report path (default: focuspath-report.html)
--max-steps <number>         Maximum observed focus stops (default: 50)
--max-tab-presses <number>   Maximum total Tab presses (default: 4 × max-steps)
--max-opaque-tab-presses <number> Repeated Tab limit per opaque host (default: 100)
--max-requests <number>      Maximum page requests (default: 500; max: 10000)
--max-screenshot-height <px> Requested height (default: 20000; max: 100000; 40 MP hard cap)
--unlimited                  Remove request/requested-height limits; the 40 MP safety cap remains
--direction <forward|reverse> Keyboard traversal direction (default: forward)
--viewport <width>x<height>  Browser viewport (default: 1440x900)
--headed                     Show Chromium while scanning
-V, --version               Show the installed FocusPath version
-h, --help                  Show command help

If Chromium is not installed yet, run npx playwright install chromium.

Node.js 24+ is the intentional tested runtime for the CLI and library. FocusPath is ESM-only; use import rather than CommonJS require().

The command exits with code 1 when an error finding is present, 2 when scanning fails, and 0 otherwise.

URLs without a scheme default to HTTPS for public hosts and HTTP for local development hosts. Embedded URL credentials are rejected by both the CLI and scanFocusPath. Query strings, screenshots, accessible names, and rendered page content may still be sensitive; protect and review HTML reports before sharing them.

TypeScript API

import { scanFocusPath } from "focuspath";
import { generateHtmlReport } from "focuspath/reporter";

const report = await scanFocusPath("https://example.com", {
  maxSteps: 60,
  maxTabPresses: 240,
  maxOpaqueTabPresses: 120,
  maxRequests: 500,
  maxScreenshotHeight: 20_000,
  direction: "reverse",
  focusSettleMs: 100,
  viewport: { width: 1440, height: 900 },
});

const html = generateHtmlReport(report);

Only absolute HTTP(S) top-level URLs are accepted by default. For a trusted local fixture, allowLocalProtocols: true explicitly enables schemes such as data: or file:; do not use that option with external input. The optional isUrlAllowed request callback is useful for application policy, but does not by itself provide DNS pinning, egress isolation, or complete SSRF protection.

The scanner currently targets Chromium and supports forward Tab or reverse Shift+Tab traversal. maxSteps limits observable report entries; maxTabPresses counts every Tab key press, including movement inside opaque hosts. Cross-origin frames and closed shadow roots inferred from repeated, uncanceled Tab movement use the independent maxOpaqueTabPresses budget. Canceled Tab events that leave focus in place are reported as stalled focus. Chromium DOM identity, not the display selector, drives stall and cycle detection. Stops affected by independently scrolling or clipping ancestors remain in the sequence with scrollContexts, including hidden/clip containers, same-origin iframe viewports and parent-page scrollers; decorative overflow does not hide a fully visible control from the overlay. Schema v4 reports use observedRect for traversal-time geometry; rect and the optional transformed quad are measured only after FocusPath interrupts smooth scrolling and stabilizes the final screenshot state. Chromium captures beyond the first viewport up to the default 20,000px maxScreenshotHeight; a shared 40-megapixel safety budget may reduce larger requested or unlimited captures according to their actual width. capture.truncated makes either cutoff explicit while capture.sourceWidth and capture.sourceHeight preserve the full page dimensions. Local scans allow 500 requests by default. visualEvidence.status distinguishes plotted, partially visible, outside-capture and sequence-only stops. network records request totals and configured resource blocking so geometry restrictions remain explicit. The HTML reporter accepts saved schema v2, v3 and v4 reports after runtime validation of their complete rendering surface. Counters, step identities, issue references, capture metadata and network totals must agree; fixed array, text, byte and 40-megapixel budgets bound processing. Screenshot evidence is restricted to the JPEG format emitted by FocusPath and must decode completely through native libjpeg-turbo with the declared dimensions. Importing focuspath/reporter keeps Playwright out of report-only consumers; the root export remains compatible. The deprecated scrollContext field mirrors the first entry for v0.4.1 compatibility. Computed outline and shadow values are recorded for manual review; FocusPath does not claim to automatically verify WCAG focus appearance.

Repository, documentation, and issue tracker: github.com/damianociarla/focuspath

MIT © Damiano Ciarla