RFC: Content-Addressable Store#912
Open
manzoorwanijk wants to merge 1 commit into
Open
Conversation
manzoorwanijk
force-pushed
the
rfc-content-addressable-store
branch
from
July 11, 2026 11:40
3538ca2 to
d2b518b
Compare
manzoorwanijk
marked this pull request as ready for review
July 11, 2026 11:43
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.
Summary
Adds an RFC for a global, file-level content-addressable store (CAS) for npm.
node_modulesis materialized from the store by copy-on-write clone or hardlink (with copy as fallback) instead of re-extracting a tarball for every package in every project. The store is a materialization backend, not an install strategy: it composes withhoisted,nested,shallow, andlinked, and introduces astore-dirconfig, apackage-import-methodconfig (auto= clone → hardlink → copy, pnpm's semantics), and annpm storecommand. No changes topackage-lock.json, the registry, ornpm publish.Motivation
npm's cache is already content-addressed and integrity-verified — but at tarball granularity, and only as a download cache: every install re-runs
tar.xper package (reify.js→pacote.extract). npm has never hardlinked or cloned a file intonode_modules.Measured on Gutenberg (2.1 GB, 102k files, macOS/APFS): five worktrees cost ~11.2 GB today vs ~1.8 GB materialized from a CAS, with the marginal worktree at ~40 MB instead of ~2.2 GB. Across two real projects, 37% of
node_modulesfiles are byte-identical duplicates. Warm-cachenpm cistill gunzips and writes every byte; with the store it creates directories and links.Notable semantics
(contentHash, mask)— the exec bit comes from bothisPackageBinand tar-header modes, so content alone is not a sufficient key. Blobs are stored read-only.EACCESon in-place writes — loud failure instead of pnpm's silent cross-project corruption); clone/copy keep today's modes bit-for-bit. Restrictive-umask installs fall back toclone-or-copyautomatically.--dangerously-allow-all-scriptsincl.binding.gypsynthesis) are never hardlinked.Linkentries silently dropped) and npm/cli#5951 (hardlink-unsupported filesystems).A separate proposal, RFC: Global Virtual Store for Linked Installs (#911), covers a symlinked machine-global virtual store for
linkedinstalls; the two share a store root layout but neither depends on the other.See the RFC for the full design, alternatives, implementation plan, tests, and unresolved questions.