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

marinate-cli

v0.4.0

Published

npm outdated, but only for packages that have had time to age safely

Readme

marinate

npm outdated, but only for packages that have had time to age safely.

Supply chain attacks on npm registries typically sit for only a few hours before being caught and pulled. Marinate wraps npm outdated and enforces a minimum aging period (default: 24 hours) before considering a package version safe to upgrade to. If you wait a day, you dodge most drive-by compromises automatically.

Install

npm install -g marinate-cli

Or run directly:

npx marinate-cli

Requires Node.js >= 18. Zero external dependencies.

Usage

marinate [options]
Package               Current   Wanted   Latest   Published          Age     Status
@types/react          19.2.13   19.2.13  19.2.14  2026-05-09 14:22   5d 2h   ready
@types/react-dom      19.2.2    19.2.2   19.2.3   2026-05-13 22:01   16h     marinating (8h left)
react                 19.2.5    19.2.5   19.2.6   2026-05-12 17:30   1d 21h  ready
react-router-dom      7.15.0    7.15.0   7.15.1   2026-05-14 11:05   3h      marinating (21h left)

2 ready, 2 marinating

Packages are either ready (published >= threshold ago) or marinating (still in the cool-down window).

Options

| Option | Default | Description | | -------------------------- | ----------- | --------------------------------------------------------------------------------------------- | | --threshold <hours> | 24 | Minimum age in hours for a release to be considered safe | | --json | | Emit JSON instead of a formatted table | | --only-ready | | Show only packages ready for upgrade | | --only-marinating | | Show only packages still in cool-down | | --strict | | Exit code 1 if any packages are still marinating | | --no-install | | Read package.json directly instead of running npm outdated (works without node_modules) | | --update | | Update ready packages and pin all versions exactly in package.json | | --update-target <target> | latest | Which version to write: latest or wanted | | --dry-run | | Preview what --update would change without writing | | --concurrency <n> | 8 | Number of parallel registry fetches | | --registry <url> | npm default | Override registry endpoint | | --no-color | | Disable ANSI color output | | -h, --help | | Show help |

Unknown flags are forwarded to npm outdated, so --workspace and --workspaces work as expected.

Examples

# CI gate: fail if any dependency was published less than 48 hours ago
marinate --threshold 48 --strict

# Automated update: bump ready packages and preview the diff
marinate --update --dry-run

# Works in CI without node_modules
marinate --no-install --json

# Machine-readable output for scripting
marinate --json --only-ready

How --update works

When you pass --update, marinate rewrites package.json in two passes:

  1. Ready packages get their version bumped to the latest (or wanted) release, pinned exactly.
  2. All remaining dependencies have their range prefixes (^, ~, >=, etc.) stripped, so every version in package.json is pinned exactly.

This ensures the package manager installs precisely the versions marinate verified as safe -- no surprise resolutions via semver ranges. File formatting is preserved. It does not run npm install -- you decide when to install.

Exit codes

| Code | Meaning | | ---- | --------------------------------------------------------------- | | 0 | No actionable findings, or --strict not set | | 1 | Marinating packages found with --strict; or invalid arguments | | 2 | Network or parse error |

What if my current package is malicious?

Marinate protects you from upgrading to a malicious release. But what if your current dependency is compromised and a fix was just published minutes ago? Marinate would flag the fix as "marinating" and block it.

In that case, use the --emergency flag to bypass the cool-down for that specific package:

marinate --update --emergency --package <package-name>

Warning: --emergency skips the cool-down window entirely (internally --threshold 0). Marinate will ask you to confirm before proceeding. This flag requires --package -- you cannot apply it globally to all dependencies at once.

A general workflow for responding to a compromised dependency:

  1. Find the CVE -- search for the CVE identifier on nvd.nist.gov, cve.org, or npm audit to confirm the vulnerability, affected versions, and fixed version.
  2. Cross-check the fix -- verify the patched version on npm advisories, Socket, or Snyk to make sure the fix is legitimate and from the expected maintainer.
  3. Update immediately -- run marinate --update --emergency --package <package-name> and confirm the prompt to pick up the fix without waiting.
  4. Run npm install and verify your build.
  5. Resume normal marination -- subsequent runs without --emergency will enforce the cool-down window again.

The --emergency escape hatch exists because security is about trade-offs: the cost of staying on a known-bad version is higher than the risk of adopting an unaged fix. Requiring an explicit package name and confirmation ensures you don't accidentally bypass the safety window for your entire dependency tree.

Claude Code hook

When an AI coding agent like Claude Code adds a dependency, it edits package.json (or runs npm install <pkg>) directly -- skipping the cool-down a human gets by running marinate first. The marinate hook command wires the gate into the agent's own edit loop so everything it adds is marinated (aged past the threshold) and sticky (pinned to an exact version).

marinate hook install        # register the hooks in ./.claude/settings.json
marinate hook status         # show whether the hooks are installed (exit 1 if not)
marinate hook uninstall      # remove only the marinate-owned hook entries

install writes two cooperating hooks into settings.json (idempotent -- re-running updates the existing entries, and unrelated hooks are left untouched):

  • PostToolUse on Edit|Write|MultiEdit -- after the agent edits a package.json, marinate diffs the added/changed dependencies, strips range prefixes to exact pins, and downgrades any still-marinating addition to the newest release that has aged past the threshold. It reports each rewrite back to the agent.
  • PreToolUse on Bash -- before any shell command runs, marinate inspects it. A one-shot npm install <pkg> / yarn add / pnpm add / bun add is blocked (it would fetch and run a fresh package immediately), with feedback naming the marinated version to pin instead. A bare npm install is allowed only once the manifest is fully marinated-and-sticky.

Both hooks call marinate hook run internally, so the logic versions with the CLI -- there are no standalone scripts to copy or keep in sync.

| Hook flag | Default | Description | | ----------------- | --------- | --------------------------------------------------------------------- | | --project | (default) | Target ./.claude/settings.json (committed, protects the whole team) | | --global | | Target ~/.claude/settings.json (every project on this machine) | | --threshold <h> | 24 | Cool-down baked into the installed hooks | | --fail-open | | On a registry/network error, warn and allow (default: fail closed) | | --dry-run | | Print the settings.json that install/uninstall would write |

Why not npm audit / Snyk / Socket?

Those tools analyze published code for known vulnerabilities. Marinate doesn't look at code at all -- it only looks at time. A package published 10 minutes ago hasn't been reviewed by anyone yet, regardless of what static analysis says. Marinate buys you that review window. Use it alongside your existing security tools, not instead of them.

License

MIT