feat(npm): serve the abbreviated packument for install-v1 clients - #959
Merged
ertime037 merged 1 commit intoSep 5, 2026
Merged
Conversation
`npm install` asks for `application/vnd.npm.install-v1+json` — the abbreviated
packument — and NORA ignored it, serving the full document to every client. The
fields it carries are exactly the ones an installer never reads: readme,
maintainers, repository, per-version description, scripts, gitHead.
The packument serve path now branches on `Accept` and projects the document down
to npm's abbreviated shape. The per-version field list is an allowlist, in one
place: dropping a field an installer consults — `os`, `cpu`, `engines`,
`peerDependenciesMeta` — silently changes what gets resolved, so a field is
added there once rather than at a call site.
`Vary: Accept` goes with it, and it is not decoration. The body now depends on a
request header while NORA still marks metadata `Cache-Control: public`; without
`Vary` a shared cache can hand the abbreviated document to a client that asked
for the full one.
The abbreviation is derived locally rather than requested upstream, so the cache
keeps exactly one canonical object per package and the full document is never
displaced by a short one.
Measured against a live upstream through the proxy, all versions preserved:
lodash 247652 -> 71989 B -70.9% 117 versions
express 804975 -> 344703 B -57.2% 288 versions
An unparsable body is served unchanged rather than turned into an error: the
client asked for a projection of this document, not for a failure.
Closes #957
Co-authored-by: ivaseeq <126263471+ivaseeq@users.noreply.github.com>
ertime037
approved these changes
Sep 5, 2026
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.
Closes #957. Stacked on #958 — that is the base branch; GitHub will retarget this to
mainonce #958 lands.What
npm installasks forapplication/vnd.npm.install-v1+jsonand NORA ignored it, serving the full packument to every client. The fields the full document carries are exactly the ones an installer never reads: readme, maintainers, repository, per-versiondescription,scripts,gitHead.The packument serve path now branches on
Acceptand projects the document down to npm's abbreviated shape.Three decisions worth a look:
os,cpu,engines,peerDependenciesMeta— silently changes what gets resolved and installed. A field gets added there once, not at a call site.Vary: Acceptis load-bearing, not decoration. The body now depends on a request header while NORA still marks metadataCache-Control: public; withoutVary, a shared cache can hand the abbreviated document to a client that asked for the full one.An unparsable body is served unchanged rather than turned into an error — the client asked for a projection of this document, not for a failure.
Measured on a polygon
Real S3 (MinIO), live upstream through the proxy, real
npm install:lodashexpressnpm installverified against both a proxied package and a hosted one.A bug the polygon caught
The first pass abbreviated the body on the stale-serve path but left
Content-Type: application/jsonon it — a short document announced as the full one. It only showed up because the polygon instance happened to serve from the stale path. Fixed by routing that branch through the same helper, andtest_npm_packument_stale_serve_honours_install_v1now asserts both thex-nora-staleprecondition and the content type, so the degraded path cannot drift from the normal one again.Tests
Four in
spec_conformance_tests:test_npm_packument_abbreviated_on_install_v1_accept— content type,Vary, dropped fields, and every resolution-affecting field asserted presenttest_npm_packument_full_without_install_v1_accept— no header, full document intacttest_npm_packument_stale_serve_honours_install_v1— the degraded path agrees with itselftest_npm_packument_unparsable_body_served_unchanged— a non-packument body is passed throughFull suite: 63 lib + 1788 bin + 6 doc, zero failures.
cargo fmt --checkandcargo clippy -p nora-registry --all-targets -- -D warningsclean.Credit
Surfaced by #889, which materializes an
install-v1.jsonalongside the full packument. That half of the idea stands on its own, and the commit carriesCo-authored-by: ivaseeq.