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

@pwa-today/pwa-check

v0.1.9

Published

An automated PWA health check tool

Readme

pwa-check

Is your web app actually ready to be installed, work offline, and behave like a real PWA?

Let pwa-check check your app for you.

It scans the HTML, manifest, scripts, and service worker, then points straight at the gaps that will hurt installability or offline behavior.

What it checks

Web App Manifest

pwa-check finds a Web App Manifest in the HTML or in JavaScript that injects it dynamically, then checks the pieces that matter for installability:

  • scope
  • display
  • start_url
  • description
  • short_name
  • orientation
  • icons
  • screenshots
  • shortcuts
  • share_target
  • file_handlers
  • handle_links

It also checks whether referenced icons, screenshots, and shortcut icons are reachable, because broken assets make a PWA look unfinished.

Viewport meta tag

It checks for the viewport configuration a polished PWA should have:

  • width=device-width
  • initial-scale=1
  • viewport-fit=cover

If tokens are missing, the warning tells you exactly what is wrong.

iOS startup images

It checks whether the app defines iOS splash screens using apple-touch-startup-image links, so the first launch does not feel half-built.

These can be present in the HTML or injected by JavaScript.

When startup-image links exist, it also checks for <meta name="apple-mobile-web-app-capable" content="yes">, which is required for those images through iOS 26.4.

Service worker

It checks whether the app registers a service worker and whether the worker does the work a PWA needs:

  • install handler
  • activate handler
  • fetch handler
  • push handler
  • notificationclick handler
  • caching behavior

It also supports Workbox-style service workers, including generated wrappers that load additional modules and precache assets.

Output

The CLI prints a list of results with one of three statuses:

  • pass
  • warn
  • fail

The process exits with a non-zero status if any fail result is found, so it fits cleanly into CI and local checks. You can also show only warnings and failures, make warnings fail the run, ignore specific warning codes, emit JSON, or set a timeout for each request.

Usage

Run the free checks against a URL when you want a straight answer instead of guessing:

node bin/pwa-check.js https://example.com

The explicit free-check command produces the same result:

pwa-check check https://example.com

or install it as a CLI tool:

npm i @pwa-today/pwa-check

then run:

npx pwa-check https://example.com

If you install the package globally:

npm i -g @pwa-today/pwa-check

or link it:

npm link @pwa-today/pwa-check

you can run it directly:

pwa-check https://example.com

Flags:

  • --json: emit machine-readable output
  • --issues-only: hide passing checks in terminal output
  • --fail-on-warn: treat warnings as failures
  • --ignore-warn <code>: exclude a warning code from --fail-on-warn
  • --timeout <ms>: cap each network request
  • --insecure-localhost: allow HTTPS requests to localhost with an invalid certificate
  • --auth-env <name>: read origin-scoped bearer/cookie authentication JSON from an environment variable
  • --auth-file <path>: read the same authentication JSON from a local file

For a protected PWA, keep the authentication value out of shell history and configuration files:

export PWA_CHECK_AUTH='{"headers":{"authorization":"Bearer token"}}'
pwa-check check --auth-env PWA_CHECK_AUTH https://app.example.com
{"cookies":[{"name":"session","value":"cookie-value"}]}

Authentication is applied only to requests for the audited origin and is removed before a cross-origin redirect. It is never printed or read from pwa-check.yml.

In terminal output, warnings and failures include their code, priority, impact, suggested fix, and documentation URL. Passing checks remain on one line.

Warning Codes

Every result includes a stable code. Warning and failure codes also include priority, impact, fix, and documentation fields in JSON output.

Use the code shown in JSON output with --ignore-warn <code> to exclude one warning from --fail-on-warn.

Paid runtime audits

Paying customers can run the hosted runtime checks with the explicit audit command. A paid plan can be purchased from https://pwa.today.

A token never enables paid checks by itself.

Set the access token in the environment:

export PWA_AUDIT_TOKEN="..."

Then start an audit:

pwa-check audit https://example.com

The CLI creates one aggregate audit, waits for the background checks to complete, prints the results, applies the quality gate, and returns:

  • 0 when the audit and quality gate pass
  • 1 when the quality gate fails
  • 2 for authentication or configuration errors
  • 3 for audit service errors or timeouts

Runtime audit flags:

  • --profile <quick|standard|full|custom>
  • --include <check-id>: include one or more comma-separated check IDs
  • --exclude <check-id>: exclude one or more comma-separated check IDs
  • --application <hostname>
  • --minimum-score <0-100>
  • --fail-on <critical|high|medium|low>
  • --config <file>
  • --poll-interval <ms>
  • --audit-timeout <ms>
  • --api-url <url>: override the default https://api.pwa.today
  • --idempotency-key <key>
  • --json
  • --auth-env <name> or --auth-file <path>: provide one-time bearer, cookie, or session-storage credentials for this hosted audit

The token can only be supplied through PWA_AUDIT_TOKEN. The API URL and idempotency key can also be set with PWA_TODAY_API_URL and PWA_TODAY_IDEMPOTENCY_KEY.

One-time audit authentication uses the same JSON shape as check, but it is sent only when the audit is created. The service encrypts it, applies it only to the target origin, and expires it after the audit. It is never read from pwa-check.yml or printed. Files passed to --auth-file must not be readable by group or others.

Hosted audits also support session storage. Each storage value must be a string:

{
  "sessionStorage": {
    "app-session": "{\"accessToken\":\"token\"}"
  }
}

The local check command uses direct HTTP requests, so session-storage authentication is supported only by pwa-check audit.

Audit configuration

The CLI automatically loads pwa-check.yml, pwa-check.yaml, or pwa-check.json from the current directory. You can select another file with --config.

version: 1

audit:
  profile: standard
  exclude:
    - push-notifications

qualityGate:
  minimumScore: 90
  failOn:
    - critical
    - high
  failOnWarnings: true

reports:
  junit: reports/pwa-audit.xml
  json: reports/pwa-audit.json

Checks with additional inputs use the stable check ID under audit.options:

audit:
  profile: full
  options:
    offline-navigation:
      series:
        - [/, /installation, /offline-support]
        - [/, /audit, /email-list]
      expectedSelectors:
        - main
        - h1
      requiredText:
        - Example

    push-notifications:
      payload:
        title: Runtime audit
        message: Test notification
    offline-request-retry:
      requestUrl: /api/messages
      method: POST
      requestBody:
        message: Test request

The service worker deployment check is opt-in because it runs a local deployment command. The CLI waits for the hosted check to capture its baseline, runs the command without a shell, waits for it to exit successfully, and then signals that the deployment is complete:

audit:
  profile: full
  include:
    - service-worker-deployment
  options:
    service-worker-deployment:
      deploymentTimeout: 900000
      commandTimeout: 900000
      command:
        - ./scripts/deploy.sh

The command and command timeout are local-only settings and are never sent to the PWA Today API. The deployment script must not exit until the deployment is finished and publicly observable.

Stable runtime check IDs:

  • manifest
  • offline
  • offline-navigation
  • service-worker-first-installation
  • service-worker-handlers
  • service-worker-update
  • service-worker-deployment (explicit opt-in only)
  • before-install-prompt
  • offline-request-retry
  • push-notifications

offline-request-retry and push-notifications require hosted check options; missing prerequisites produce not-applicable. A selected service-worker-deployment check requires a local command and missing local configuration is a CLI configuration error.

Testing

Run the test suite with:

npm test

License

ISC. See LICENSE.

Notes

  • The checker uses heuristics for dynamic behavior, such as manifests or service workers injected by JavaScript.
  • A warn result means the app might still work, but it is leaving quality on the table.
  • A fail result means the app is missing a required piece and should not be treated as install-ready.