bun-pm-update-audit
v0.0.3
Published
Safely preview Bun dependency updates with workspace-aware reports and package diffs.
Maintainers
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.lockformat
The legacy binary bun.lockb format is intentionally not parsed.
Quick start
No installation is required:
bunx bun-pm-update-auditExample 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:
- Reads the original
bun.lock. - Snapshots
bun.lockand all workspacepackage.jsonfiles recorded there. - Runs
bun update --lockfile-only --ignore-scripts .... - Reads the temporary updated lockfile.
- Restores every snapshotted file.
- Verifies the restored files byte-for-byte using xxHash3.
- Resolves each workspace's logical dependency routes in both lockfiles.
- Compares the versions reached by those routes, independent of Bun's raw hoisted/nested lock keys.
- Runs
bun pm difffor 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-auditBun'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 --latestAudit selected packages
bunx bun-pm-update-audit react zodWorkspaces / monorepos
bunx bun-pm-update-audit -r--workspaces is accepted as a convenience alias for Bun's --recursive:
bunx bun-pm-update-audit --workspacesFilter 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/typescriptis 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 --summaryor:
bunx bun-pm-update-audit --no-diffExample:
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 --rawWithout --diff-args, the tool invokes Bun with no extra diff options:
bun pm diff package@old-version new-versionThat means Bun's own native diff defaults remain the defaults for this tool.
JSON output
bunx bun-pm-update-audit --jsonJSON 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-updatesThis is useful for scheduled CI checks.
Run against another directory
bunx bun-pm-update-audit --cwd ./apps/webCLI 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/*' --latestThe 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-versionAdded, 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 auditA useful workflow is:
bun audit
bunx bun-pm-update-audit --latestProgrammatic 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-runCreate a package tarball:
bun pm packPublish to npm:
bun publishor:
npm publishLicense
MIT
