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

bun-pm-update-audit

v0.0.3

Published

Safely preview Bun dependency updates with workspace-aware reports and package diffs.

Readme

bun-pm-update-audit

Safely preview what bun update would resolve, inspect the actual package changes with bun pm diff, and leave your project exactly as it was.

The default output is an audit view: each changed resolution is shown with its affected workspaces, followed by Bun's full package diff. Use --summary (or --no-diff) when you only want the compact version-change report.

Requirements

  • Bun 1.4.0 or newer
  • A project using the text bun.lock format

The legacy binary bun.lockb format is intentionally not parsed.

Quick start

No installation is required:

bunx bun-pm-update-audit

Example default output:

react 19.1.0 -> 19.1.1 [patch]
workspaces: apps/web (direct), apps/admin (direct)
------------------------------------------------------------------------

<normal bun pm diff output>

scheduler 0.26.0 -> 0.26.1 [patch]
workspaces: apps/web (transitive), apps/admin (transitive)
------------------------------------------------------------------------

<normal bun pm diff output>

The package diff is run once per unique package/version transition even when multiple workspaces use that resolution.

How it works

bun-pm-update-audit:

  1. Reads the original bun.lock.
  2. Snapshots bun.lock and all workspace package.json files recorded there.
  3. Runs bun update --lockfile-only --ignore-scripts ....
  4. Reads the temporary updated lockfile.
  5. Restores every snapshotted file.
  6. Verifies the restored files byte-for-byte using xxHash3.
  7. Resolves each workspace's logical dependency routes in both lockfiles.
  8. Compares the versions reached by those routes, independent of Bun's raw hoisted/nested lock keys.
  9. Runs bun pm diff for each diffable package change unless summary/JSON mode was requested.

If restoration fails, the temporary safety backup is retained and its path is reported.

Usage

bunx bun-pm-update-audit [packages...] [bun update options...]
bunx bun-pm-update-audit [update options...] --diff-args [bun pm diff options...]

Arguments before --diff-args that are not tool-specific options are forwarded to bun update.

Audit compatible updates

bunx bun-pm-update-audit

Bun's normal update rules are used, so versions stay within the ranges declared in your manifests unless you ask Bun to do otherwise.

Audit latest versions

bunx bun-pm-update-audit --latest

Audit selected packages

bunx bun-pm-update-audit react zod

Workspaces / monorepos

bunx bun-pm-update-audit -r

--workspaces is accepted as a convenience alias for Bun's --recursive:

bunx bun-pm-update-audit --workspaces

Filter workspaces using Bun's native filter syntax:

bunx bun-pm-update-audit --filter './packages/*'

Workspace attribution is preserved in the report. A dependency directly listed by a workspace is marked direct; a package reached through another dependency is marked transitive.

Example:

react       19.1.0 -> 19.1.1  patch  apps/web (direct), apps/admin (direct)
scheduler   0.26.0 -> 0.26.1  patch  apps/web (transitive), apps/admin (transitive)
typescript  5.8.3 -> 5.9.2    minor  root (direct)

Bun may move an unchanged package between a hoisted lock key and a nested workspace key while updating some other workspace. Those lock-key relocations are ignored: the report compares the package/version reached by the logical dependency route instead of treating the raw key as package identity.

Nested Bun lockfile resolutions are followed as well. For example, a lock key such as:

dts-bundle-generator/typescript

is treated as the typescript resolution nested under dts-bundle-generator, not as the root typescript resolution.

Compact summary output

The package diff is the default. To only show changed versions/workspaces:

bunx bun-pm-update-audit --summary

or:

bunx bun-pm-update-audit --no-diff

Example:

3 package updates

react       19.1.0 -> 19.1.1  patch  apps/web (direct), apps/admin (direct)
scheduler   0.26.0 -> 0.26.1  patch  apps/web (transitive), apps/admin (transitive)
typescript  5.8.3 -> 5.9.2    minor  root (direct)

--show-diff is still accepted for compatibility, but it is now redundant because package diffs are already enabled by default.

Passing options to bun pm diff

Everything after --diff-args is passed verbatim to every bun pm diff invocation.

Examples:

bunx bun-pm-update-audit --diff-args --stat
bunx bun-pm-update-audit --diff-args --name-only
bunx bun-pm-update-audit --diff-args -U 10
bunx bun-pm-update-audit --latest --diff-args --raw

Without --diff-args, the tool invokes Bun with no extra diff options:

bun pm diff package@old-version new-version

That means Bun's own native diff defaults remain the defaults for this tool.

JSON output

bunx bun-pm-update-audit --json

JSON mode is a structured summary and does not run bun pm diff, so stdout remains valid JSON.

Example:

{
  "cwd": "/repo",
  "count": 2,
  "workspaces": [
    {
      "path": "",
      "name": "my-monorepo"
    },
    {
      "path": "apps/web",
      "name": "@acme/web",
      "version": "1.0.0"
    }
  ],
  "changes": [
    {
      "name": "react",
      "lockKeys": ["react"],
      "from": "19.1.0",
      "to": "19.1.1",
      "kind": "patch",
      "diffable": true,
      "workspaces": [
        {
          "path": "apps/web",
          "name": "@acme/web",
          "version": "1.0.0",
          "direct": true
        }
      ]
    },
    {
      "name": "scheduler",
      "lockKeys": ["scheduler"],
      "from": "0.26.0",
      "to": "0.26.1",
      "kind": "patch",
      "diffable": true,
      "workspaces": [
        {
          "path": "apps/web",
          "name": "@acme/web",
          "version": "1.0.0",
          "direct": false
        }
      ]
    }
  ]
}

path: "" represents the repository root workspace. Pretty output renders it as root.

lockKeys is an array because Bun can represent the same package/version transition at more than one resolution location. Identical transitions are collapsed so the actual package diff is not printed repeatedly.

CI

Normally the command exits successfully when updates are found. To fail when there are available updates:

bunx bun-pm-update-audit --summary --fail-on-updates

This is useful for scheduled CI checks.

Run against another directory

bunx bun-pm-update-audit --cwd ./apps/web

CLI options

| Option | Description | | --- | --- | | --cwd <dir> | Run against another project directory. | | --summary | Print version/workspace changes only; skip package diffs. | | --no-diff | Alias for --summary. | | --show-diff | Compatibility flag; package diff is already the default. | | --diff-args | Pass all remaining arguments to bun pm diff. | | --json | Emit a structured JSON report; implies summary mode. | | --fail-on-updates | Exit with code 1 when updates are available. | | --workspaces | Convenience alias for Bun's --recursive. | | --version | Print the package version. | | -h, --help | Show CLI help. |

Examples of Bun update options forwarded normally:

bunx bun-pm-update-audit --dev --latest
bunx bun-pm-update-audit --prod
bunx bun-pm-update-audit --no-optional
bunx bun-pm-update-audit --filter './packages/*' --latest

The following update options are rejected because they conflict with the snapshot/restore model:

  • --dry-run
  • --no-save
  • --frozen-lockfile
  • --global / -g
  • --interactive / -i
  • --yarn

A bare -- can still be used to force the remaining arguments into the bun update pass-through set. --diff-args then starts the diff-specific argument section.

Safety model

The command is designed to leave the project exactly as it found it.

--lockfile-only avoids installing into node_modules, but Bun may still populate its global install cache while resolving dependencies.

The tool also forces --ignore-scripts; an update audit should not execute project lifecycle scripts merely to inspect dependency resolution.

bun pm diff

For every changed package that has both an old and new published semver version, the default audit mode runs the equivalent of:

bun pm diff package@old-version new-version

Added, removed, workspace/file/git-style, or otherwise non-semver resolutions remain visible in the report but are not passed to bun pm diff.

Bun documentation:

  • https://bun.sh/docs/pm/cli/update
  • https://bun.sh/docs/pm/cli/pm#diff
  • https://bun.sh/docs/pm/lockfile

This is not bun audit

Despite the package name, this command audits updates. It does not query the npm security advisory API.

For known vulnerability reporting, use Bun's built-in command:

bun audit

A useful workflow is:

bun audit
bunx bun-pm-update-audit --latest

Programmatic API

For only the change array, the original API remains available:

import { checkUpdates } from "bun-pm-update-audit";

const changes = await checkUpdates({
  cwd: process.cwd(),
  latest: true,
  recursive: true,
});

For the full workspace-aware report:

import { auditUpdates } from "bun-pm-update-audit";

const report = await auditUpdates({
  latest: true,
  recursive: true,
});

console.log(report.workspaces);
console.log(report.changes);

You can invoke package diffs programmatically and pass Bun diff options:

import { auditUpdates, showPackageDiffs } from "bun-pm-update-audit";

const report = await auditUpdates({ latest: true });

await showPackageDiffs(report.cwd, report.changes, {
  diffArgs: ["--stat"],
});

There is also a pure lockfile comparison helper:

import { diffLockfiles } from "bun-pm-update-audit";

const report = diffLockfiles(oldLockText, newLockText, process.cwd());

Publishing

Inspect what will be published:

bun pm pack --dry-run

Create a package tarball:

bun pm pack

Publish to npm:

bun publish

or:

npm publish

License

MIT