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

deployproof

v0.3.0

Published

Prove a preview behaves like production before you deploy.

Readme

DeployProof

CI CodeQL npm MIT license

Prove that a preview deployment behaves like production before you merge it. DeployProof sends the same bounded request to both environments, then compares the behavior that commonly drifts between them: status codes, redirect chains, final paths, cache and security headers, cookie attributes, canonical URLs, robots directives, and titles.

It is read-only, does not need credentials, and never prints response bodies, cookie values, or custom request-header values.

Custom request headers are sent only to the selected base origin and its same-origin redirects. DeployProof drops them if a redirect leaves that origin. Query-string values are represented by deterministic fingerprints in reports, including URLs surfaced by network errors, so differences remain detectable without printing the original values.

Quick start

npx deployproof \
  --preview https://my-pr.example.workers.dev \
  --production https://example.com \
  / /docs /api/health

Exit code 0 means every route passed. Exit code 1 means a behavioral difference was found. Exit code 2 means DeployProof could not run.

Configuration

Create deployproof.config.json:

{
  "production": "https://example.com",
  "routes": [
    "/",
    "/docs",
    {
      "path": "/api/health",
      "method": "GET",
      "expect": {
        "status": 200,
        "contentType": "application/json"
      }
    }
  ],
  "timeoutMs": 10000,
  "maxRedirects": 5,
  "maxBodyBytes": 512000
}

Pass the preview URL from CI:

DEPLOYPROOF_PREVIEW="$PREVIEW_URL" npx deployproof --strict

The CLI also reads DEPLOYPROOF_PRODUCTION, so URLs never have to live in the configuration file.

Path prefixes in preview and production URLs are preserved. For example, a route of /api/health under https://preview.example.com/deployments/123 requests /deployments/123/api/health.

Content type expectations match the response media type case-insensitively. Parameters such as charset=utf-8 do not affect the match. Custom request header names and values are validated when configuration loads, before any request is made. Malformed configuration errors identify the file without echoing its contents, so header values cannot leak through JSON parser diagnostics. The timeout applies independently to every request in a redirect chain, including reading the final HTML response body. Order-only differences in Cache-Control, CORS token lists, and Vary are normalized so equivalent header behavior does not create noisy reports. Canonical links and robots directives are recognized with quoted or unquoted HTML attribute values.

GitHub Action

- uses: loke-dev/[email protected]
  with:
    preview: ${{ steps.deploy.outputs.deployment-url }}
    production: https://example.com
    strict: true

The Action emits native annotations for each route difference. It compares cookie names and security attributes such as Secure, HttpOnly, and the SameSite mode, but never exposes cookie values. Absolute cookie expiration timestamps are normalized so equivalent rolling sessions do not create drift; the presence of Expires is still compared. It runs the reviewed CLI bundle from the selected repository tag without downloading executable code from npm.

Routes can be supplied without a configuration file:

- uses: loke-dev/[email protected]
  with:
    preview: ${{ steps.deploy.outputs.deployment-url }}
    production: https://example.com
    routes: |
      /
      /docs
      /api/health
    timeout: "10000"
    strict: true

See the integration guide and ready-to-adapt workflow recipes for GitHub deployments, Vercel, Cloudflare, and Netlify.

Output formats

deployproof --format human   # readable terminal report
deployproof --format json    # automation and dashboards
deployproof --format github  # workflow annotations
deployproof --format sarif   # code scanning upload

Use --strict to make warnings fail the check. Errors always fail. Notices remain informational.

Library API

The same bounded comparison engine used by the CLI is available as an ESM library:

import { prove, type ProofConfig } from "deployproof";

const config: ProofConfig = {
  preview: "https://my-pr.example.workers.dev",
  production: "https://example.com",
  routes: [{ path: "/" }, { path: "/api/health", method: "HEAD" }],
  timeoutMs: 10_000,
  maxRedirects: 5,
  maxBodyBytes: 512_000,
  ignoreHeaders: [],
};

const result = await prove(config);

prove performs read-only requests and returns structured ProofResult data. It preserves the CLI's safety properties: bounded response reads and redirects, redacted query values, no response bodies, and no cookie or custom-header values in results.

What DeployProof catches

| ID | Difference | Default severity | | --- | --- | --- | | DP000 | Request failed or timed out | error | | DP001 | HTTP status | error | | DP002 | Final path and query | error | | DP003 | Redirect chain | warning | | DP004 | Cache, content, and security headers | notice or warning | | DP005 | Cookie names or security attributes | warning | | DP006 | Title, canonical, or robots metadata | notice or warning | | DP007 | Explicit status expectation | error | | DP008 | Explicit response media type expectation | error |

Response bodies are read only for HTML metadata, capped at 500 KB by default, and never included in output.

Route method values are normalized case-insensitively during configuration loading, so get, GET, and HEAD are all supported.

Development

pnpm install
pnpm check
pnpm dev -- --preview http://localhost:4173 --production https://example.com

DeployProof is MIT licensed. Product documentation is at deployproof.loke.dev.