Conversation
The v2/v3 line scanner needs npm's own formatting, and the format check matched indented text, so a compact package-lock.json parsed to zero dependencies. Keep the scanner for canonical lockfiles and decode the document when it reads nothing.
andrew
force-pushed
the
npm-compact-lockfile
branch
from
September 27, 2026 05:57
2a0098d to
d6dc7b7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A compact
package-lock.jsonparsed to zero dependencies. The v2/v3 path was chosen by matching indented text in the first 200 bytes ("lockfileVersion": 3), and the scanner it selects reads entries line by line, so a document without npm's own formatting fell through to the v1 nesteddependenciestree or parsed as nothing.The line scanner stays as the primary path, since npm writes one key per line and reading it without decoding the document is what keeps large lockfiles cheap. When it comes back empty the document is decoded with a streaming JSON decoder instead, which reads the
packagesentries in document order and handles the v1 tree. Both paths now fill the same entry type and share one conversion to a dependency, andinternal/npm.TestPackageLockPathsAgreerequires them to produce identical results on the fixtures npm wrote.Dispatch is by which key the document has rather than by how it is spaced: no
"packages"anywhere means v1. On the 2.2MB 10,000-package benchmark, canonical v3 is unchanged at 15.6ms and canonical v1 costs 4.5% more for that one scan (18.9ms to 19.8ms); a compacted document of the same size parses in 20.7ms where it previously returned nothing.A lockfile carrying a
packagessection is now read from it whateverlockfileVersionit declares, and direct dependencies come from the root""entry even when it appears after the packages that reference it.