Content-addressable store
Understand shared package content, writable dependency links, integrity checks, and store cleanup.
LPM CLI saves package content in a shared store. Projects reuse that content and dependency layouts, which reduces repeat downloads and copies.
# Find the store
lpm store path
# Inspect its structure and integrity records
lpm store verify --deep
# Preview data that no installed project uses
lpm cache pruneThe store supports npm, LPM.dev Registry, private registries, and non-registry sources. It is not specific to LPM.dev Registry.
Content and dependency layouts
The default store has two main parts:
| Part | Purpose |
|---|---|
| Package objects | Canonical package content, identified by source integrity. |
| Link entries | Writable package files and links to the dependencies that the package needs. |
Two packages with the same content integrity can reuse one object. Two projects with compatible dependency layouts can also reuse a link entry.
A package name and version are not enough to identify a link entry. Its identity also includes platform, non-registry source identity, peers, dependency targets, aliases, linker mode, and patches.
Peer context matters in both hoisted and isolated layouts. Packages with different peers can require separate entries even when their names and versions match.
How an install reuses content
An install can reuse an existing object after validation. Otherwise, it downloads or reads the source, validates its integrity, and extracts the package. Extraction leaves out a .git directory or file at any depth, under any spelling Git reads as .git: another letter case, a zero-width mark that HFS+ or a Linux casefold directory leaves out of names, the dots and spaces Windows drops from a name's end (.git.), its NTFS short name git~1, an NTFS stream name after it (.git:x), or any of these after a \ in a name, which Windows reads as a directory. Git would read one as a repository of its own wherever the package is committed, as a deploy output's packages are, and refuses to commit a path under the other spellings.
LPM CLI creates writable package files from that object through a filesystem clone or copy. It adds dependency links and records the entry's metadata.
New entries are staged and published with an atomic rename. Incomplete entries do not count as reusable packages.
Reuse includes validation of package content, recorded dependency links, and the package slots beside the owning package. Missing or changed dependency links trigger a rebuild from the object. Malformed metadata can return an error.
Deleting a project's node_modules does not delete the shared store. A later install can reuse valid stored data.
Writable files and sharing
Canonical objects and writable package files use separate file identities. A write through node_modules does not change the canonical object.
However, projects that reuse one link entry share its writable package files. A manual edit can affect another project that uses that entry.
For lasting dependency changes, use lpm patch. A patch gets a distinct entry and remains part of the project's installation contract.
| Filesystem | How writable files are created |
|---|---|
| macOS on APFS | Copy-on-write clones. |
| Linux with reflink support | Copy-on-write file clones. |
| Linux without reflink support | Independent file copies. |
| Windows | Independent file copies. |
Copy-on-write clones share physical storage until a write occurs. They still have separate file identities. Writable entries do not use hardlinks to canonical objects.
Project links
A typical project dependency points into a shared link entry:
project/node_modules/react
→ ~/.lpm/store/v2/links/<entry>/node_modules/reactThe entry contains package-local dependency links. Project executable shims live in node_modules/.bin.
The default hoisted layout exposes root dependencies at the project root. It does not place every transitive dependency there.
Workspaces default to isolated layout. Both layouts use shared objects and link entries. See lpm install for layout selection.
Store location
The default root is ~/.lpm/store/. LPM_HOME moves the LPM home, including the store:
LPM_HOME=/path/to/lpm-data lpm install
LPM_HOME=/path/to/lpm-data lpm store pathUse the same LPM_HOME for installation and maintenance. The LPM home also holds your login and local env secrets, so another LPM_HOME starts without your saved login. See Files LPM CLI creates.
Network filesystems can make the store slower because installation performs many file and metadata operations.
Store versions
| Version | Status | Content layout |
|---|---|---|
| v1 | Legacy | Package directories identified by name and version. |
| v2 | Default | Package objects and shared dependency layouts. |
| v3 | Experimental | File blobs and tree records, plus shared dependency layouts. |
LPM_STORE_VERSION=v3 lpm install
LPM_STORE_VERSION=v2 lpm installLPM CLI does not select v3 automatically. The versions can coexist. lpm store verify and lpm store clean inspect or remove all versions.
lpm.json has no store-version setting. Use LPM_STORE_VERSION for this choice.
Default v2 layout
~/.lpm/store/v2/
├── objects/<integrity>/
├── links/<entry>/
│ ├── node_modules/<package>/
│ └── .lpm-link-meta.json
└── compat/<entry>/The metadata connects each link entry to its object and dependency targets. Compatibility caches support tools that need a project-local dependency layout on macOS.
Experimental v3 layout
v3 also stores file blobs, package-tree records, and source records. Identical files can share stored data across different packages.
Canonical object projections can share hardlinks with immutable blobs inside the store. Writable package entries still use independent file identities.
Existing content migrates when an install needs it. Switching layouts does not eagerly copy the complete store.
Integrity checks
Source integrity identifies the downloaded archive. It does not mean that every expanded file is rehashed on every install.
For reused v2 objects, choose a policy:
lpm config integrity --set source
lpm config integrity --set tree| Policy | Behavior |
|---|---|
source | Default. Validates the saved source identity without rehashing every expanded file. |
tree | Validates expanded package content. Metadata snapshots avoid unnecessary repeat hashing. |
An environment value overrides the saved policy for one process:
LPM_V2_OBJECT_INTEGRITY=tree lpm installv3 validates source and tree records. It checks blob metadata and rehashes blobs when that metadata changes.
These checks differ from lpm install --strict-integrity, which requires inline integrity for direct tarball URLs before first use.
lpm store verify --deep parses manifests, compares applicable integrity records, and rehashes v3 blobs. It does not rehash all expanded v1/v2 files.
Project links connect locked instances to their stored entries for integrity comparison. Unrelated entries with the same name and version are not interchangeable.
The report states how many locked package records it compared. Records without a binding through installed links or a readable integrity marker remain unexamined. Legacy installs usually copy package files into the project, so their lockfile comparison can remain partial. Structural checks still cover the global store.
Security analysis
Source analysis during installation is off by default. Enable it through lpm config source-analysis:
lpm config source-analysis --set true
lpm installStored analysis can reduce repeat scanning. It does not replace registry verdicts, vulnerability lookups, or analysis of changed installed files.
lpm audit can analyze installed source independently. Its network checks have a separate scope from the local store cache.
Cleanup and recovery
Preview unreferenced data before removal:
lpm cache prune
lpm cache prune --applyPruning traces installed project links. A retained lockfile alone does not keep its store data alive.
If project discovery is unavailable, supply explicit project paths. See lpm cache prune for discovery failures, age limits, and cleanup scope.
For an integrity error, inspect the report:
lpm store verify --deep --json > store-report.jsonlpm store verify --fix refreshes security-analysis caches. It does not restore missing package files or repair arbitrary corruption.
For a complete reset, lpm store clean removes every store version without confirmation. Projects then need installation again.
See also
lpm install— install packages and select a dependency layoutlpm cache— inspect caches and prune unused store datalpm store— verification output and complete resetslpm patch— keep dependency changes reproduciblelpm rebuild— dependency scripts and native-build caches- Lockfile — recorded sources and integrity
- Environment variables — data-root and store selectors