locksift
v0.1.0
Published
See exactly which dependencies a lockfile change adds, removes, or bumps — review the supply-chain surface of a PR. Zero dependencies, no account.
Downloads
100
Maintainers
Readme
locksift
See what a lockfile change actually did to your dependencies. A PR touches
package-lock.json and the diff is 4,000 unreadable lines — you can't tell which
packages were added (the supply-chain surface you actually need to eyeball),
which got a major bump, which were quietly downgraded. locksift turns that
noise into a short, reviewable changelog. Zero dependencies, no account, no
network.
# What did my uncommitted changes do to the tree?
npx locksift package-lock.json --git
Added (2) — new in tree, review these
+ [email protected]
+ [email protected]
Removed (1)
- [email protected]
Changed (2)
↑ chalk 4.1.2 → 5.3.0 [major]
↓ semver 7.5.4 → 7.3.8 [downgrade]
+2 -1 ~2 (1 major, 1 downgrade)Why
The big supply-chain incidents all enter the same way: a new (often transitive)
package lands in your lockfile and nobody looks, because the lockfile diff is
unreadable by design. git shows you thousands of churned hash/resolved lines;
what you want is the dependency-level answer — what's new, what's gone, what
jumped a major. locksift computes exactly that from the lockfile itself. It
runs locally, talks to nothing, and needs no registry token.
Usage
# Diff two lockfiles
locksift old/package-lock.json new/package-lock.json
# Diff your working tree against a git ref (default HEAD) — the PR-review case
locksift package-lock.json --git
locksift package-lock.json --git main
# Just the new packages, one per line — pipe into review tooling
locksift package-lock.json --git --added-only
# Machine-readable
locksift a.json b.json --json
# CI gate: fail the job if the lockfile changed at all
locksift package-lock.json --git --exit-codeOptions
| Flag | Effect |
|------|--------|
| --git [ref] | Compare the working-tree lockfile against ref (default HEAD) |
| --json | Emit { added, removed, changed, summary } as JSON |
| --added-only | Print only newly added packages as name@version, one per line |
| --exit-code | Exit 1 when there are any changes (for CI gates) |
| -v, --version | Print version |
| -h, --help | Show help |
Supported lockfiles
| File | Notes |
|------|-------|
| package-lock.json | lockfileVersion 1, 2, and 3. v2/v3 read the authoritative packages map; v1 walks the nested dependencies tree; workspace source dirs are skipped. When a package resolves to several versions in one tree, the diff compares a single representative (the last seen in traversal). |
| Pipfile.lock | pipenv — both default and develop sections. Entries without a pinned version (git/VCS/editable/local-path installs) are not surfaced. |
Both are plain JSON, which is what keeps locksift dependency-free.
Bump classification
A changed package is tagged by comparing the numeric major.minor.patch core
(range prefixes like ^, ~, v and prerelease/build suffixes are tolerated):
[major]/[minor]/[patch]— the first component that moved up[downgrade]— the new version is lower than the old (worth a second look)[other]— same numeric core, different string (e.g. prerelease tag changed)
--json carries the same bump value per changed entry, plus a summary with
majors and downgrades counts.
Exit codes
| Code | Meaning |
|------|---------|
| 0 | success (default — even when changes are found) |
| 1 | changes found and --exit-code was passed |
| 2 | error (bad args, unreadable/invalid lockfile, git failure) |
By default locksift is a viewer and exits 0; add --exit-code to make it a
gate (the git diff --exit-code convention).
License
MIT
