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

uxinspect

v0.11.0

Published

All-in-one UI/UX testing — browser automation, AI-powered exploration, accessibility audit, performance scores, visual diff. Tests like a real human.

Readme

uxinspect

All-in-one UI/UX testing — tests like a real human, every click, every screen, every accessibility rule, in one CLI.

npm license checks

What it does

One command runs everything you need to ship a frontend with confidence:

  • Real-user flows — clicks, types, navigates, just like a person
  • Accessibility audit — full WCAG check on every page
  • Performance scores — Core Web Vitals, LCP, CLS, TBT
  • Visual diff — pixel-perfect regression detection across viewports
  • Auto-exploration — bot clicks every button, finds the bugs you forgot
  • AI mode (optional) — act("checkout the cart") survives UI redesigns
  • One HTML report — every result, every screenshot, in one place

Install

npm install -g uxinspect
npx playwright install chromium

Quick start

uxinspect run --url https://example.com --explore

Open ./uxinspect-report/report.html to see results.

Config file

// uxinspect.config.ts
import type { InspectConfig } from 'uxinspect';

export default {
  url: 'https://example.com',
  viewports: [
    { name: 'desktop', width: 1280, height: 800 },
    { name: 'mobile', width: 375, height: 667 },
  ],
  flows: [
    {
      name: 'signup',
      steps: [
        { goto: 'https://example.com/signup' },
        { fill: { selector: '#email', text: '[email protected]' } },
        { click: 'button[type=submit]' },
        { waitFor: '.welcome' },
      ],
    },
  ],
  checks: { a11y: true, visual: true, perf: true, explore: true },
  parallel: true,
  reporters: ['html', 'json', 'junit', 'sarif', 'allure', 'tap'],
  ai: { enabled: true },
} satisfies InspectConfig;
uxinspect run --config ./uxinspect.config.ts

Programmatic API

import { inspect } from 'uxinspect';

const result = await inspect({
  url: 'https://example.com',
  checks: { a11y: true, visual: true, explore: true },
});

if (!result.passed) process.exit(1);

Programmatic helpers

Composable helpers that sit alongside inspect() for specialized flows and integrations.

flaky — retry with flake detection

Re-runs a block until it passes, classifies intermittent failures as flakes.

import { retryWithFlakeDetection, inspect } from 'uxinspect';

const result = await retryWithFlakeDetection(
  () => inspect(config),
  { maxAttempts: 3 },
);

websocket — WebSocket flow support

Drive WebSocket endpoints with a step-based flow.

import { runWebSocketFlow } from 'uxinspect';

await runWebSocketFlow({
  url: 'wss://example.com/socket',
  steps: [
    { send: '{"type":"ping"}' },
    { expect: { contains: 'pong' } },
  ],
});

graphql — GraphQL flow support

Query/mutation steps with variable interpolation and assertions.

import { runGraphQLFlow } from 'uxinspect';

await runGraphQLFlow({
  endpoint: 'https://example.com/graphql',
  steps: [
    { query: '{ viewer { id } }', expect: { path: 'data.viewer.id' } },
  ],
});

service-worker — Service Worker audit

Checks registration, scope, cache strategy, and update flow.

import { auditServiceWorker } from 'uxinspect';

const report = await auditServiceWorker(page);

rum — Real User Monitoring

Collect field metrics from a page, or inject the RUM client script into production.

import { collectRUM, rumClientScript } from 'uxinspect';

const metrics = await collectRUM(page);

// In your production HTML:
// <script>${rumClientScript()}</script>

github-annotations — GitHub Actions PR annotations

Emits ::error / ::warning workflow commands so findings surface as inline PR annotations.

import { emitGitHubAnnotations } from 'uxinspect';

emitGitHubAnnotations(result);

amp — AMP HTML validation

Validates AMP markup on the current page.

import { validateAmp } from 'uxinspect';

const ampReport = await validateAmp(page);

bdd — Gherkin feature file runner

Parse Gherkin syntax, map steps to flows, and hand them to inspect().

import { readFileSync } from 'node:fs';
import { parseFeature, featureToFlows, builtinSteps, inspect } from 'uxinspect';

const feature = parseFeature(readFileSync('login.feature', 'utf8'));
const flows = featureToFlows(feature, builtinSteps);
await inspect({ url: 'https://example.com', flows });

mailbox — email intercept for signup flows

Wait for a verification email during a test run.

import { waitForEmail } from 'uxinspect';

const email = await waitForEmail(
  { provider: 'mailpit', baseUrl: 'https://mail.example.com' },
  { subjectContains: 'Verify' },
);

Checks

100+ built-in audits. 65+ wired into inspect() single-run (enable via checks or --all); all available as library imports.

Accessibility & UX

| Check | Key | One-liner | |---|---|---| | Accessibility | a11y | WCAG violations via axe-core on every viewport | | Keyboard | keyboard | Focus trap, tab order, visible focus rings | | Touch targets | touchTargets | WCAG 2.5.5 / 2.5.8 target-size (44/24 px) audit | | Dead clicks | deadClicks | Flags elements that look clickable but do nothing | | Motion prefs | motionPrefs | prefers-reduced-motion, dark-mode, print, forced-colors | | Forms | forms | Label, autocomplete, required, validation audit |

checks: {
  a11y: true,
  keyboard: true,
  touchTargets: true,
  deadClicks: true,
  motionPrefs: true,
  forms: true,
}

Performance

| Check | Key | One-liner | |---|---|---| | Lighthouse | perf | Core Web Vitals + Lighthouse scoring | | Long tasks | longTasks | Long tasks, LoAF attribution, INP capture | | CLS timeline | clsTimeline | Layout shift timeline with node attribution | | Bundle size | bundleSize | JS/CSS byte budget + duplicate package detection | | Webfonts | webfonts | font-display, FOIT/FOUT, oversize font files | | Images | imageAudit | Alt text, lazy-load, modern format, intrinsic dims | | Resource hints | resourceHints | preload / prefetch / preconnect audit | | Cache headers | cacheHeaders | Cache-Control, ETag, immutable audit | | Compression | compression | gzip / brotli + HTTP/2 / HTTP/3 negotiation |

checks: {
  perf: true,
  longTasks: true,
  clsTimeline: true,
  bundleSize: true,
  webfonts: true,
  imageAudit: true,
  resourceHints: true,
  cacheHeaders: true,
  compression: true,
}

Security

| Check | Key | One-liner | |---|---|---| | Headers | security | CSP, HSTS, X-Frame-Options, Referrer-Policy, etc. | | Passive smells | passiveSecurity | Surface-level security red flags | | Retire.js | retire | Vulnerable JS library scan (12 lib signatures) | | TLS | tls | Socket audit: protocol, cipher, cert chain | | Exposed paths | exposedPaths | Sensitive path scan (35 signatures) | | Mixed content | mixedContent | Insecure resources on HTTPS pages |

checks: {
  security: true,
  passiveSecurity: true,
  retire: true,
  tls: true,
  exposedPaths: true,
  mixedContent: true,
}

SEO & Content

| Check | Key | One-liner | |---|---|---| | SEO | seo | Meta tags, heading structure, canonical | | Sitemap | sitemap | sitemap.xml fetch + schema validation | | Robots | robotsAudit | robots.txt + meta robots + X-Robots-Tag | | Structured data | structuredData | JSON-LD, microdata, hreflang | | Open Graph | openGraph | OpenGraph + Twitter Card validation | | Content quality | contentQuality | Flesch-Kincaid readability + duplicate detection | | Links | links | Broken link check across crawled pages |

checks: {
  seo: true,
  sitemap: true,
  robotsAudit: true,
  structuredData: true,
  openGraph: true,
  contentQuality: true,
  links: true,
}

Network & Infra

| Check | Key | One-liner | |---|---|---| | PWA | pwa | Manifest + service worker audit | | Redirects | redirects | Redirect chain length + loop detection | | Crawl | crawl | BFS site crawl with configurable depth | | Third-party | thirdParty | Tracker / ad / analytics script analysis |

checks: {
  pwa: true,
  redirects: true,
  crawl: true,
  thirdParty: true,
}

Visual

| Check | Key | One-liner | |---|---|---| | Visual diff | visual | Pixelmatch diff against stored baselines |

checks: { visual: true }

Privacy & Compliance

| Check | Key | One-liner | |---|---|---| | Cookie banner | cookieBanner | GDPR consent popup detection | | Console errors | consoleErrors | Browser console capture across the run |

checks: {
  cookieBanner: true,
  consoleErrors: true,
}

Exploration

| Check | Key | One-liner | |---|---|---| | Explore | explore | Heuristic automated crawling + interaction | | AI | ai | Keyless AI instructions (Playwright role/text locators) |

checks: {
  explore: true,
  ai: true,
}

CLI flags

Every check has a matching flag. Use --all to turn them all on, or pick individually. Flags are boolean; prefix with --no- to disable (e.g. --no-a11y).

Core flags

| Flag | Default | Description | |------|---------|-------------| | --url | required | URL to inspect | | --config | — | Config file (.ts / .js / .json) | | --out | ./uxinspect-report | Report directory | | --baselines | ./uxinspect-baselines | Visual baseline directory | | --headed | false | Run with visible browser | | --parallel | false | Run flows in parallel | | --storage-state | — | Path to auth storageState JSON | | --reporters | html,json | Comma list: html, json, junit, sarif, allure, tap | | --publish | — | Dashboard URL to upload report | | --publish-token | — | Bearer token for dashboard upload | | --all | false | Enable every check below |

Check flags

| Category | Flag | |---|---| | Accessibility & UX | --a11y --keyboard --touch-targets --dead-clicks --motion-prefs --forms | | Performance | --perf --long-tasks --cls-timeline --bundle-size --webfonts --image-audit --resource-hints --cache-headers --compression | | Security | --security --passive-security --retire --tls --exposed-paths --mixed-content | | SEO & Content | --seo --sitemap --robots-audit --structured-data --open-graph --content-quality --links | | Network & Infra | --pwa --redirects --crawl --third-party | | Visual | --visual | | Privacy & Compliance | --cookie-banner --console-errors | | Exploration | --explore --ai |

Example:

uxinspect run --url https://example.com --all
uxinspect run --url https://example.com --a11y --perf --retire --seo --visual

Reporters

Pick any combination via reporters: [...] or --reporters html,json,....

| Reporter | Output | Use | |---|---|---| | html | report.html | Human-readable dashboard with screenshots | | json | report.json | Machine-readable full result tree | | junit | junit.xml | CI test result ingestion | | sarif | report.sarif | Code scanning / security tab ingestion | | allure | allure-results/ | Directory for the Allure UI | | tap | report.tap | TAP 14 stream for TAP-compatible tooling |

AI without keys

{ ai: 'click the login button' } resolves natural language to Playwright locators (role → label → placeholder → title → text → CSS). Survives most UI redesigns. Zero API keys required.

Cloud dashboard (optional)

Self-host a dashboard worker with R2 storage. Push reports from CI:

uxinspect run --url https://example.com \
  --publish https://uxinspect-dashboard.example.workers.dev \
  --publish-token $TOKEN

See dashboard/ for the worker source and wrangler.toml.

R2 visual baselines (optional)

Set env vars to share baselines across machines/CI:

export UXINSPECT_R2_ACCOUNT_ID=...
export UXINSPECT_R2_BUCKET=uxinspect-baselines
export UXINSPECT_R2_ACCESS_KEY_ID=...
export UXINSPECT_R2_SECRET_ACCESS_KEY=...

Local files still mirror; R2 is the source of truth.

Serve a saved report

uxinspect report ./uxinspect-report --port 4173

How it compares

| Capability | uxinspect | E2E frameworks | Visual SaaS | A11y plugins | |---|:-:|:-:|:-:|:-:| | Real-user clicks | yes | yes | — | — | | Multi-browser | yes | partial | — | — | | Accessibility | yes | plugin | — | yes | | Performance | yes | — | — | — | | Visual diff | yes | plugin | paid | — | | Security headers | yes | — | — | — | | Vuln JS scan | yes | — | — | — | | SEO / structured data | yes | — | — | — | | Auto-explore | yes | — | — | — | | AI helpers | yes | — | — | — | | One report | yes | — | — | — | | Open source | MIT | mixed | no | yes |

License

MIT