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

@mouadlouhichi/pnpms

v0.1.0

Published

A strict malware gate for pnpm installs, powered by OSV malicious-package advisories.

Readme

pnpms

A strict malware gate for pnpm installs.

pnpms is a small wrapper around pnpm. Before it installs dependencies, it resolves the requested dependency tree into pnpm-lock.yaml, checks every exact public npm package/version against OSV malicious-package advisories (MAL-*), and only then lets pnpm perform a frozen install.

It is designed to block known malicious or compromised npm releases, including a malicious transitive dependency introduced by an otherwise legitimate package.

What it does

pnpms add example-package
       │
       ├─ 1. pnpm add example-package --lockfile-only --ignore-scripts
       │      Resolves the exact tree; no node_modules installation stage.
       │
       ├─ 2. Read every exact public npm name@version from pnpm-lock.yaml
       │
       ├─ 3. Query OSV in batches and retain MAL-* advisories only
       │
       ├─ malware found ──> restore package.json / pnpm-lock.yaml; exit 1
       │
       └─ clean ──────────> pnpm install --frozen-lockfile

The final frozen install prevents a second dependency-resolution decision after the malware check.

Install

pnpms is not published yet in this repository. After you publish it, install a pinned/verified release rather than blindly executing an untrusted npx command.

npm install --global @mouadlouhichi/pnpms
# or, during development from this checkout:
npm link

Then use pnpms in place of pnpm for dependency-changing commands:

pnpms install
pnpms add zod
pnpms add -D typescript
pnpms update
pnpms fetch

Default security behavior

offlinePolicy is strict by default:

  • A MAL-* hit always blocks the operation.
  • An unreachable, malformed, or incomplete OSV response blocks the operation.
  • A malicious hit remembered in the local cache also blocks while offline.
  • Clean results are checked live by default (cacheTtlHours: 0). Teams can opt into a bounded clean-result cache to reduce repeated API calls.

For a deliberate emergency override during an OSV outage only:

pnpms --pnpms-allow-offline install

That option never overrides a positive malware finding. It only allows an install when the intelligence service cannot answer. Use it sparingly and log its use in CI.

Force fresh checks rather than using cached clean results:

pnpms --pnpms-refresh install

Scan an existing lockfile

pnpms scan
pnpms --pnpms-refresh scan

This is useful in CI, after a newly disclosed supply-chain incident, or before a production deploy.

Configuration

Create a starter configuration file:

pnpms config init

This writes pnpms.config.json in the project/workspace root:

{
  "offlinePolicy": "strict",
  "cacheTtlHours": 0,
  "requestTimeoutMs": 10000
}

The same keys can be placed in the root package.json under pnpms:

{
  "pnpms": {
    "offlinePolicy": "strict",
    "cacheTtlHours": 1,
    "batchSize": 500
  }
}

Configuration precedence, from lowest to highest:

  1. built-in defaults;
  2. package.json#pnpms;
  3. pnpms.config.json;
  4. PNPMS_* environment variables;
  5. --pnpms-* command-line options.

Useful environment variables:

PNPMS_OFFLINE_POLICY=strict        # strict | warn
PNPMS_CACHE_TTL_HOURS=6
PNPMS_REQUEST_TIMEOUT_MS=10000
PNPMS_BATCH_SIZE=500
PNPMS_CACHE_DIR=/secure/cache/pnpms

Use pnpms config show to view the resolved configuration and pnpms cache clear to remove the local advisory cache.

Commands and compatibility

Guarded now

  • install, i
  • add, a
  • update, up
  • fetch
  • scan (pnpms command)

Most other pnpm commands are delegated unchanged because they do not resolve/install a new registry dependency.

Deliberately refused in 0.x

These commands can download and execute a package without the project-lockfile transaction used by pnpms:

  • pnpm add -g / other global install paths;
  • pnpm dlx;
  • pnpm create;
  • pnpm exec --package ...;
  • pnpm import and pnpm install-test;
  • guarded installs using --no-lockfile or a custom --lockfile-dir.

pnpms fails rather than silently allowing those as bypasses. Future versions can add a separately designed, temporary-lockfile workflow for them.

Important limitations

pnpms is a known-malware gate, not a guarantee that a dependency is safe.

  • A brand-new or undisclosed compromise is not in an advisory feed yet.
  • OSV data can be delayed, corrected, or incomplete.
  • A developer can bypass the check by running pnpm directly. Enforce pnpms in CI and team tooling.
  • Explicit git, file:, local/workspace, and explicitly non-public registry tarballs are not sent to OSV. pnpms prints a warning for such entries rather than falsely identifying a private package with the same name as a public malicious package.
  • pnpms leaves normal pnpm lifecycle-script behavior unchanged during the final install. It prevents a known malicious version before that phase; it does not replace pnpm script-approval or sandboxing controls.

For stronger defense in depth, also commit lockfiles, use --frozen-lockfile in CI, limit registry access, pin trusted publishing, use pnpm’s build-script approval controls, and set a release-age cooldown for new dependencies.

CI example

- name: Install guarded dependencies
  run: pnpms install --frozen-lockfile

- name: Re-scan lockfile before release
  run: pnpms --pnpms-refresh scan

Because a frozen install already has an exact lockfile, pnpms scans it first and delegates to pnpm only if no known malicious version is found.

Development

Requirements: Node.js 20+ and pnpm 9+ for real projects.

npm install --ignore-scripts
npm test
npm run check
npm run pack:check

The test suite covers lockfile parsing, OSV response validation, cache behavior, strict outage behavior, the malicious-package block, and rollback of staged files.

Publishing checklist

  1. Confirm that you are signed in to the intended npm scope: npm whoami.

  2. Update package.json repository metadata and version.

  3. Run npm audit --omit=dev, npm test, npm run check, and npm run pack:check.

  4. Inspect the resulting tarball with npm pack.

  5. For the first interactive release, publish with your account’s security-key 2FA enabled:

    npm publish --access public

    For later automated releases, configure an npm trusted publisher and publish from that protected CI workflow with provenance enabled.

License

MIT. See LICENSE.