A 3,000-line package-lock.json diff tells you nothing. lockscope tells you everything: which packages appeared, which vanished, which changed — with semver arrows and major/minor/patch bucketing so you can spot the risky upgrades at a glance. Supports lockfile v1 and v2/v3 formats, and diffs across them.
- 🔼 Semver arrows —
1.0.0 → 2.1.0with color-coded majors - 🧮 Summary —
+added −removed ~changed (major · minor · patch)totals - 🧩 v1 ↔ v3 — diff legacy trees against modern lockfiles
- 📦 CLI + library — use in scripts or import the API
- 🪶 Zero runtime dependencies — TypeScript, ESM, tiny
lockscope old-package-lock.json package-lock.jsonnpm install -g lockscope
# one-shot
npx lockscope old.json new.json# compare against the last commit
git show HEAD:package-lock.json > /tmp/old.lock
lockscope /tmp/old.lock package-lock.json
# audit a PR
lockscope base.lock pr.lock --json | jq '.stats'
# library
import { parseLock, diffLocks, summarize } from "lockscope";| Flag | Description |
|---|---|
--json |
{ changes: [...], stats: {...} } |
--only-changes |
hide the summary block |
--color M |
always | auto | never |
-V, --help |
version / help |
Exit codes: 0 compared · 2 bad input/unreadable file.
import { parseLock, diffLocks, summarize, semverDelta } from "lockscope";
const before = parseLock(oldJsonString);
const after = parseLock(newJsonString);
const changes = diffLocks(before, after); // [{ kind: "changed", name: "a", from: "1.0.0", to: "2.1.0", dev: false }]
const stats = summarize(changes, before, after); // { added: 0, removed: 0, changed: 1, major: 1, ... }npm install
npm test # 13 tests: v1/v3 parsing, cross-format diffs, CLI e2e- yarn.lock / pnpm-lock.yaml support
-
--critical-only(major bumps + security advisories via registry) -
--why— transitive path explanation for a changed package - GitHub Action that comments the summary on PRs
PRs welcome — npm test must pass, zero runtime deps stays.
MIT © 2026 v01dst