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

@foxom/hookseal

v0.1.0

Published

Audit npm package-lock install hooks with a small explicit allowlist.

Readme

hookseal

hookseal audits npm package-lock.json files for dependency install hooks that can execute during npm install or npm ci.

Recent npm supply-chain incidents keep landing in the same place: developer and CI machines run lifecycle scripts from packages before humans have reviewed what changed. hookseal makes that boundary explicit. It reads the committed lockfile, finds dependencies marked with hasInstallScript, and fails unless they are in a small reviewed allowlist.

Why this exists

npm audit is useful after a vulnerability is known. Install hooks are earlier in the chain: a new transitive package can gain execution just because a lockfile changed. Larger commercial scanners can cover this, but small projects often need a local, deterministic CI check that does not call an external service.

hookseal is intentionally narrow:

  • It scans npm lockfiles offline.
  • It focuses on lifecycle hook execution, not every package risk.
  • It uses explicit allowlists instead of scoring packages by popularity.
  • It works as both a library and a CLI.

Install

Install from npm:

npm install -D @foxom/hookseal

Requires Node.js 20 or newer.

CLI usage

Audit the current project:

npx hookseal

Audit another directory:

npx hookseal ./packages/web

Allow a reviewed dependency hook:

npx hookseal --allow esbuild --allow @parcel/[email protected]

Use JSON output in CI:

npx hookseal --json --fail-on medium

Ignore dev-only dependency hooks:

npx hookseal --no-dev

Policy file

Create .hookseal.json at the project root:

{
  "allow": [
    "esbuild",
    "@parcel/[email protected]"
  ],
  "allowedRootScripts": [
    "prepare"
  ]
}

Allow by exact package name when any version is acceptable, or by package@version when you want the review to expire on upgrade.

Library usage

import { auditPackageLock, formatTextReport } from "@foxom/hookseal";

const lockfile = {
  lockfileVersion: 3,
  packages: {
    "": { name: "app", version: "1.0.0" },
    "node_modules/esbuild": {
      version: "0.25.0",
      integrity: "sha512-example",
      hasInstallScript: true
    }
  }
};

const report = auditPackageLock(lockfile, {
  allowedPackages: ["[email protected]"]
});

console.log(report.ok);
console.log(formatTextReport(report));

API

auditProject(options)

Reads package-lock.json, optional package.json, and optional .hookseal.json from options.cwd.

Options:

  • cwd: project directory. Default: process.cwd().
  • lockfile: lockfile path relative to cwd. Default: package-lock.json.
  • packageJson: package metadata object for direct API use.
  • policyPath: policy file path, or false to disable policy loading.
  • allowedPackages or allow: package names or package@version entries.
  • allowedRootScripts: root lifecycle scripts allowed in package.json.
  • includeDev: include dev-only dependencies. Default: true.

auditPackageLock(lockfile, options)

Audits a parsed package lock object and returns:

  • ok: true when no findings are present.
  • lockfileVersion: detected lockfile version.
  • packageName and packageVersion: root package metadata when available.
  • totals: finding counts by severity.
  • findings: sorted findings with rule id, severity, package, path, message, and remediation.

formatTextReport(report, options)

Formats a human-readable terminal report. Pass { verbose: true } to include resolved tarball URLs.

shouldFail(report, threshold)

Returns whether a report should fail CI for low, medium, or high.

Checks

  • HS001: dependency declares an install lifecycle script and is not allowed.
  • HS002: root package.json defines an install lifecycle script and is not allowed.
  • HS003: dependency declares an install lifecycle script without integrity metadata.
  • HS004: lockfile has no packages metadata, so hook status cannot be verified.

Design notes

hookseal relies on npm lockfile metadata instead of installing packages or fetching tarballs. That keeps it safe to run before install and makes it useful in CI review gates. The tradeoff is scope: it only knows what the lockfile records. If a project uses another package manager, pair it with that manager's own hook approval mechanism.

The allowlist is small on purpose. Native builders and platform packages often need install hooks, but each hook should be an explicit review decision, not lockfile noise.

This is not a package-manager wrapper and it does not mutate package.json. Tools such as install-script blockers can control whether scripts run; hookseal is the review gate that answers a narrower question from committed files: "Did this lockfile introduce executable dependency hooks that we have not approved?"

Development

npm install
npm test
npm run typecheck
npm pack --dry-run

Run the CLI locally:

node bin/hookseal.js --help

License

MIT