LPM CLI

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 prune

The 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:

PartPurpose
Package objectsCanonical package content, identified by source integrity.
Link entriesWritable 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.

FilesystemHow writable files are created
macOS on APFSCopy-on-write clones.
Linux with reflink supportCopy-on-write file clones.
Linux without reflink supportIndependent file copies.
WindowsIndependent 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.

A typical project dependency points into a shared link entry:

project/node_modules/react
  → ~/.lpm/store/v2/links/<entry>/node_modules/react

The 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 path

Use 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

VersionStatusContent layout
v1LegacyPackage directories identified by name and version.
v2DefaultPackage objects and shared dependency layouts.
v3ExperimentalFile blobs and tree records, plus shared dependency layouts.
LPM_STORE_VERSION=v3 lpm install
LPM_STORE_VERSION=v2 lpm install

LPM 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
PolicyBehavior
sourceDefault. Validates the saved source identity without rehashing every expanded file.
treeValidates 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 install

v3 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 install

Stored 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 --apply

Pruning 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.json

lpm 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