lpm install
Install project dependencies, add packages, and reproduce installs from a lockfile.
lpm install installs project dependencies into node_modules and records their resolved versions in a lockfile.
lpm install [OPTIONS] [PACKAGES]...
lpm i [OPTIONS] [PACKAGES]...LPM CLI works with npm, LPM.dev Registry, and private registries through .npmrc.
Only @lpm.dev/* packages always use LPM.dev Registry. See Registries.
Quickstart
From a project with package.json, install its dependencies:
lpm installAdd a dependency or a development tool:
lpm install zod
lpm install -D vitestLPM CLI updates package.json, writes lpm.lock, and installs the packages.
Commit lpm.lock. Current installs use TOML only.
Choose an install mode
| Goal | Command |
|---|---|
Install the dependencies in package.json | lpm install |
| Add one or more dependencies | lpm install react react-dom |
| Add a development dependency | lpm install -D typescript |
| Install a global command | lpm install -g typescript |
| Reproduce a committed lockfile | lpm ci |
| Install a Swift dependency from LPM.dev Registry | lpm install @lpm.dev/owner.swift-pkg |
At a workspace root, a no-argument install includes all members and the root. From a member directory, it applies to that member. See Workspaces.
Dependency scripts require trust or an explicit script policy. Root project scripts have separate rules. See Lifecycle scripts.
Project configuration
Dependencies and project install configuration belong in package.json:
{
"dependencies": {
"zod": "^4.3.0"
},
"lpm": {
"linker": "isolated",
"strictPeerDependencies": true
}
}lpm install
lpm install --linker=hoisted --no-strict-peer-dependenciesThe second command overrides these two values for one run.
lpm.json has no install configuration block.
Its runtime pins can affect the Node version available to engine checks and lifecycle scripts.
| File | Purpose |
|---|---|
package.json > lpm | Linker, peer rules, script policy, overrides, catalogs, and release-age policy |
.npmrc | Registry routing and registry credentials |
lpm.toml | Project save defaults, typosquat exceptions, and sandbox configuration |
~/.lpm/config.toml | User defaults and security configuration |
Precedence depends on the field. The linker, script policy, and peer sections describe their rules.
Project discovery
LPM CLI searches from the current directory for the nearest ancestor with package.json.
Manifest changes, lockfiles, and node_modules belong to that project. Workspace members use the shared root lockfile.
If no ancestor has a manifest, a package-add command creates a minimal package.json in the current directory.
A no-argument install fails because there are no declared dependencies to install.
Examples
lpm install zod@4.3.6 # save an exact version
lpm install 'zod@^4.3.0' # preserve a version range
lpm install zod --exact # resolve a version and save it exactly
lpm install --prod # omit development dependencies
lpm install --omit=dev,optional # omit both dependency types
lpm install --catalog react # save through the default catalog
lpm install --catalog=ui react # save through a named catalog
lpm install react --filter web # add to one workspace member
lpm install --no-recursive # install only the current project
lpm install --force # resolve, download, and link again
lpm install --json --timing # include timing in JSON outputProduction and omitted deps
--prod and --production omit development dependencies from node_modules.
--omit accepts dev and optional, separated by commas or repeated:
lpm install --prod
lpm install --omit=optional
lpm install --omit=dev --omit=optionalThe lockfile retains the dependency graph. Production installs retain peers that the remaining production packages need.
-D cannot combine with --prod or --omit=dev.
Frozen lockfile and CI
Use lpm ci in automation:
lpm ciThis command requires lpm.lock and never rewrites either lockfile.
lpm install --frozen-lockfile has the same lockfile contract.
If CI is detected and lpm.lock exists, a regular install uses frozen mode automatically.
Use --no-frozen-lockfile for an intentional mutable install in CI.
Frozen installs reject package arguments, --force, a missing lockfile, and changes to the locked project configuration.
This configuration includes dependency sections, overrides, catalogs, patches, peer rules, and autoInstallPeers.
lpm.lock records the overrides and patches that its resolution used. A fresh clone of a project with overrides or patches therefore installs from the committed lockfile, without local state from an earlier install.
If the manifest changes, run a mutable install locally:
lpm installReview and commit the updated lockfiles before you retry CI.
Offline installs
Populate the store from a committed lockfile with lpm fetch. Then install from the local store:
lpm fetch
lpm install --offline --frozen-lockfileOffline installs require a matching lockfile and all required package data in the store. If data is missing, the install fails. Offline installs also skip background update requests.
An offline install also fails when the overrides in package.json differ from the ones lpm.lock was resolved with.
A lockfile from an earlier release can lack that record. If such a project has overrides, the offline install fails until one online install rewrites the lockfile.
In either case, run lpm install online, commit the lockfile, then retry --offline.
Lifecycle scripts and configured policy extensions can still access the network through their own processes.
--offline does not accept package arguments. Add or change dependencies during an online install, then commit the resulting lockfile.
For Docker layers, see Docker deploys.
Save policy
A package name without a version saves as ^resolvedVersion by default.
Without catalog conversion, explicit versions and ranges remain as written. Prerelease versions selected from a name or tag save exactly.
| Request | Saved value, if the resolved version is 4.3.6 |
|---|---|
lpm install zod | "^4.3.6" |
lpm install zod@latest | "^4.3.6" |
lpm install zod@4.3.6 | "4.3.6" |
lpm install 'zod@^4.3.0' | "^4.3.0" |
lpm install zod --exact | "4.3.6" |
lpm install zod --tilde | "~4.3.6" |
--exact, --tilde, and --save-prefix are mutually exclusive.
An explicit version or range takes precedence over these flags.
Without catalog conversion, a bare reinstall preserves the saved specification unless a save flag requests a new range. Save flags preserve existing source dependencies, including catalog entries that identify sources.
Identical package arguments run once. Conflicting requests for the same local name fail before manifest changes.
Set persistent save defaults in lpm.toml or ~/.lpm/config.toml:
save-prefix = "^"
save-exact = falseSee Save policy for tags, prereleases, and precedence.
Catalogs
To add a package through an existing root catalog entry, use:
lpm install --catalog react
lpm install --catalog=ui reactThese commands save catalog: or catalog:ui in the target manifest.
The entry must exist, and its range must include the resolved version. Otherwise, the install fails without a committed manifest change.
--catalog cannot combine with --exact, --tilde, or --save-prefix.
lpm.catalogMode | Automatic behavior |
|---|---|
manual (default) | Resolve existing catalog references, but do not create them automatically |
prefer | Save through a matching default catalog entry. Warn and retain a direct version spec on mismatch |
strict | Require a matching default catalog entry for each added registry dependency |
Automatic catalog modes take precedence over explicit registry versions, save flags, and existing registry ranges. They preserve workspace, local-path, alias, Git, and tarball sources. --catalog cannot replace a source dependency.
lpm.cleanupUnusedCatalogs = true removes unused root catalog entries after a successful install.
The default preserves them. See Catalogs.
Dependency overrides
Override a direct or transitive dependency in package.json:
{
"lpm": {
"overrides": {
"ms": "2.1.3"
}
}
}An override replaces the matching dependency range. An exact override can select a version outside the original range. Security and platform restrictions still apply.
Field precedence is lpm.overrides, then top-level overrides, then resolutions.
Workspace-root overrides apply to all members. Members can extend or replace selectors within the same field.
If the override is unavailable or blocked by policy, LPM CLI warns and retains the natural version. See Override selectors.
Workspaces
From the workspace root, install all members and the root:
lpm install
lpm install --no-recursive # root project only
lpm install --workspace-concurrency=1 # sequential member installsFrom a member directory, use --recursive to include the owning workspace:
lpm install --recursiveRequired workspace dependencies run before their consumers. The root runs last.
LPM CLI chooses concurrency automatically. --workspace-concurrency <N> overrides LPM_WORKSPACE_CONCURRENCY and the automatic choice.
A value of 1 forces sequential execution.
Filter a refresh from the workspace root:
lpm install --filter web --fail-if-no-match
lpm install --filter-prod webA filtered refresh includes required workspace dependencies and omits unrelated members and the root.
From a member directory, add --recursive to a filtered refresh.
Add packages to selected manifests:
lpm install react --filter web
lpm install -D typescript -w
lpm install react --filter './apps/*' --yes--recursive cannot combine with package arguments. -w applies only to package additions and cannot combine with workspace filters.
--filter-prod excludes development edges from workspace selection.
It does not replace --prod, which controls the installed dependency types.
See Workspace filters for patterns and Git-based selection.
In an interactive terminal, additions to multiple members require confirmation.
--yes, --json, and non-interactive input skip this confirmation.
Shared workspace lockfile
Workspace installs use one lpm.lock at the root, with a separate dependency record for each member.
Member-local commands update their own record. Workspace lockfiles do not produce lpm.lockb.
A recursive install commits the shared lockfile only after all selected projects succeed. A successful migration also removes obsolete member lockfiles. A failure preserves those lockfiles.
An interrupted or failed install can leave provisional node_modules changes.
The next install reconciles those files with the authoritative lockfile.
It also removes rollback directories under .lpm that a killed workspace install left behind.
Dependency sources
Registry packages follow registry routing, including private registries from .npmrc.
Local directories, links, archives, and Git dependencies retain their own source identity.
Packages with the same name and version can still refer to different sources.
Declare source dependencies in package.json, then run lpm install. Explicit package arguments support workspace:. Alias, Git, local-path, and tarball version tokens are rejected.
Local package archives
Declare a local archive in the manifest:
{
"dependencies": {
"example": "file:vendor/example-1.0.0.tgz"
}
}lpm installLPM CLI installs the archive and its registry dependencies, including aliases and optional dependencies. It does not install the archive's development dependencies. Nested local, workspace, Git, or archive dependencies inside that archive are unsupported.
The lockfile records the archive content hash. If the archive changes, a mutable install updates the lockfile. A frozen install rejects changed content.
Keep the archive at its declared path, including for a frozen install with an empty store.
Relative paths cannot contain ... Use an absolute path for an archive outside the project.
Local archive reads have a 500 MiB limit.
GitHub dependencies
Declare a public GitHub dependency:
{
"dependencies": {
"ci-info": "git+https://github.com/watson/ci-info.git#main"
}
}GitHub shorthand such as github:owner/repository#ref also works.
LPM CLI resolves branches and tags to a commit, then records the commit and archive integrity in lpm.lock.
An exact 40-character commit needs no ref lookup.
Private repositories, authenticated URLs, non-GitHub hosts, and non-HTTPS Git transports are unsupported. GitHub URLs cannot contain credentials, custom ports, or query parameters. Redirects are rejected.
Frozen and offline installs reuse the locked commit and integrity from the store. Registry dependencies inside the Git package remain part of the locked graph. Nested non-registry dependencies are unsupported.
JSR dependencies
{
"dependencies": {
"@std/path": "jsr:@std/path@^1.1.0",
"@std/fs": "jsr:^1.0.0"
}
}LPM CLI preserves the declared import names and fetches the npm-compatible packages from https://npm.jsr.io.
Version-only specs use the dependency key as the JSR package name.
An .npmrc entry for @jsr:registry can select a mirror. See JSR routing.
Swift packages
Use LPM.dev Registry packages with a Swift package or Xcode project:
lpm install @lpm.dev/owner.swift-pkg
lpm install @lpm.dev/owner.swift-pkg --yesLPM CLI checks existing SwiftPM configuration before changing project files, then configures Swift Registry access automatically.
Malformed or unsupported configuration stops installation. --force preserves this check.
For Package.swift, it adds the dependency and runs Swift package resolution.
Existing products retain their conditions and module aliases. Version updates preserve comments and other products from the same package.
If the CLI cannot safely edit a requirement expression, it stops without changing the manifest.
For an Xcode project, it manages Packages/LPMDependencies, connects that wrapper package to the project, and resolves dependencies.
A single eligible target is selected automatically. Multiple targets open a selector.
For non-interactive use, --yes selects the first eligible target.
In a workspace, the selected member must contain its own Package.swift or .xcodeproj.
Swift dependencies do not enter package.json.
If an install fails, LPM CLI restores the affected Swift manifests and resolution files. If a JavaScript dependency fails later in a mixed request, the Swift changes also roll back.
Swift JSON output includes registry_setup with scope, signing_certificate, and signing_trust.
Each value is repaired or retained. Xcode results also identify the project type, wrapper package, and target.
For version-specific manifests, the CLI selects products with the resolving SwiftPM tools version. Xcode installs require matching SwiftPM and Xcode tools versions before project edits.
See Swift Registry setup and Using Swift packages.
Global installs
Install one executable package per command:
lpm install -g typescriptGlobal installs expose commands through ~/.lpm/bin/ and record packages under ~/.lpm/global/.
They do not change the current project's manifest or read its lpm configuration.
CLI flags and user configuration control the supported install policies.
A package must provide at least one usable executable. Otherwise, the global install rolls back.
Resolve a command-name collision explicitly:
lpm install -g foo --alias serve=foo-serve
lpm install -g foo --replace-bin serve--alias installs the declared executable under another name.
--replace-bin transfers the existing command name to the new package.
Global installs reject workspace flags, -D, --yes, omission flags, catalog flags, frozen flags, --offline, --force, --skills, --timing, and audit-after-install flags.
--no-skills and --no-security-summary have no effect on global installs.
After lpm approve-scripts --global, reinstall the affected global package to run its approved scripts.
See Global packages.
How it works
LPM CLI resolves dependencies, downloads missing package data into ~/.lpm/store/, then links packages into the project.
Cached package data can be reused across projects.
The default standalone layout is hoisted.
Direct dependencies appear at the project root. LPM CLI does not flatten every transitive dependency into the root node_modules directory.
Workspaces default to isolated, which restricts dependency visibility.
Without an explicit linker choice, incompatible peer requirements also switch an install to isolated.
The lockfile preserves that automatic decision for subsequent installs.
lpm install --linker=isolated
lpm install react --linker=hoistedLinker precedence is: CLI flag, user linker configuration, LPM_LINKER, project lpm.linker, then the automatic default.
Project package files are separate from canonical store files. Supported filesystems can share their physical storage through copy-on-write. Other filesystems use independent copies. See Package storage and Lockfiles.
Peer dependency strict mode
Missing required peers install automatically by default. Missing optional peers do not.
Set lpm.autoInstallPeers = false to disable automatic peer installation.
The alternative resolver selected by LPM_RESOLVER=pubgrub does not support this behavior.
By default, unresolved required peers, version mismatches, and conflicting peer requirements produce warnings. Use strict mode to make these conditions fail the install:
lpm install --strict-peer-dependencies
lpm install --no-strict-peer-dependenciesPrecedence is: CLI flag, lpm.strictPeerDependencies, user strict-peer-dependencies, then false.
An absent optional peer does not cause a strict-mode failure.
JSON output includes diagnostics under peer_issues.
Engines enforcement
LPM CLI enforces the workspace root's engines.lpm and engines.node requirements.
It also checks engines.node for each selected dependency.
A required dependency with an incompatible Node requirement fails the install. An incompatible dependency reachable only through optional edges is skipped. These checks also apply to warm, frozen, and offline installs.
The Node version comes from the script PATH, including selected managed runtimes.
LPM CLI records the version each Node executable reports, and asks again when the executable, the project's Node version files, or version-manager settings change.
It asks version-manager shims every time, and lpm install --force always asks.
LPM CLI does not install a runtime to satisfy an engine range.
If no compatible Node is available, select one with lpm use:
lpm use node@22
lpm installUse warning-only checks for one run:
lpm install --no-engine-strictPersistent values are lpm.engineStrict = false or user engine-strict = false.
Precedence is: CLI flag, project configuration, user configuration, then enforcement enabled.
Other package-manager engine keys produce warnings and are not enforced.
Lifecycle scripts
No-argument installs run these root project scripts:
| Timing | Scripts, in order |
|---|---|
| Before dependency installation | pnpm:devPreinstall |
| After successful installation | preinstall, install, postinstall, preprepare, prepare, postprepare |
Package additions do not run this root lifecycle.
Root scripts are separate from dependency script policy and do not use the dependency sandbox.
There is no --ignore-scripts option for install.
Commands inside workspace hooks
Workspace lifecycle hooks cannot start another command that needs the same install lock. The child command fails with a parent-installation conflict.
Run these commands after installation. Commands that need no install lock, such as lpm --help, remain available inside hooks.
Dependency scripts
Unapproved dependency scripts are blocked by default.
Review the blocked packages with lpm approve-scripts:
lpm install
lpm approve-scripts
lpm rebuildlpm rebuild runs approved dependency scripts.
The executable dependency phases are preinstall, install, and postinstall.
Other detected phases, including dependency prepare, do not run during install.
| Policy | Behavior |
|---|---|
deny (default) | Block unapproved dependency scripts |
allow | Run dependency install scripts without individual trust approval |
triage | Trust recognized safe commands automatically. Delegated files need review. Other scripts need approval or an approved advisor verdict |
Set the policy with --policy=deny|allow|triage. --yolo means allow, and --triage means triage.
Precedence is: CLI flag, lpm.scriptPolicy, user script-policy, then deny.
Changes that weaken the approved security policy can require security approval.
If all unbuilt scripted packages are trusted, automatic builds run.
The effective allow policy also starts automatic builds.
This includes existing trust approvals, green triage results, and applicable advisor approvals.
For a mixture of trusted and blocked packages, request an automatic build of the trusted subset:
lpm install --auto-build
lpm install example --auto-buildProject lpm.scripts.autoBuild = true or user autoBuild = true also enables this behavior for project installs.
Global installs use the explicit --auto-build flag.
lpm.scripts.denyAll = true prevents dependency script execution, including automatic builds.
If an executed script fails, the install fails and identifies the package and script.
Optional LLM advisor under triage
An advisor can review scripts that need additional triage. Approvals apply only to the current install and do not create permanent trust.
lpm install --triage --advisor=claude-cli
lpm install --triage --advisor=noneSupported values are none, claude-cli, codex, and ollama.
Precedence is: CLI flag, lpm.triageAdvisor, user triage-advisor, then none.
The advisor runs only under triage. It reviews every phase that needs approval, including delegated scripts. Packages with a Red phase cannot receive automatic advisor approval. See Script review.
Sandbox
Dependency scripts use a filesystem sandbox by default. Default mode permits outbound network access. Strict mode also restricts environment variables and outbound network access.
lpm install --auto-build --strict-sandbox--paranoid is an alias for --strict-sandbox.
--no-sandbox removes containment and exposes the host environment to dependency scripts. It can require security approval.
These three flags are mutually exclusive.
Sandbox support depends on the operating system and available isolation features. If required protection is unavailable, execution can fail. See Dependency sandbox behavior for platform requirements and permitted file access.
Security controls
Guarded weakeners and approvals
Some changes require approval, including weaker script policy, sandbox disablement, cooldown bypasses, and provenance exceptions. An interactive command can request approval inline.
CI, --json, and non-interactive commands return security_approval_required with a suggested unlock command.
--yes does not authorize a weaker security policy.
Weaker values in repository files also require an explicit unlock instead of an inline prompt.
Package-scoped unlocks do not authorize blanket provenance exceptions.
See lpm security for temporary project exceptions and the approved machine policy.
Typosquat guard
The typosquat guard is disabled by default. Enable it with lpm config:
lpm config typosquat --set onThe guard checks new direct dependency names before resolution.
In an interactive terminal, a suspicious name can be replaced or added to the project exception list.
CI, --json, non-interactive input, and --yes instead return typosquat_suspected.
Intentional exceptions belong in lpm.toml:
[[policy.typosquat.allow]]
package = "axois"
similar-to = "axios"
reason = "Intentional internal compatibility package"Existing locked direct dependencies are not new names. Transitive dependencies are outside this guard's scope. See Typosquat configuration.
Recently published packages
The minimum release age is disabled by default. Enable a one-day cooldown:
lpm config release-age --set 1dThe default scope covers direct dependencies.
For a range, LPM CLI selects the newest eligible version that satisfies the range.
For latest, it also respects the registry's current latest tag.
An exact version that is too recent fails instead of selecting another version.
Set lpm.minimumReleaseAgePolicy = "strict" to include transitive dependencies.
Locked publication timestamps also enforce this policy during lockfile replay.
lpm install example --min-release-age=1h
lpm install example --min-release-age-exclude example
lpm install example --allow-newExclusions accept a package name, an exact version, or @scope/*.
For aliases, use the canonical package name. CLI, project, and user exclusions merge.
Cooldown exceptions do not bypass provenance checks or approve dependency scripts.
See lpm trust release-age-exclude and release-age configuration.
Registry signatures and trust policy
Install-time registry signature checks are disabled by default. Enable them or run a separate signature audit:
lpm config signatures --set true
lpm audit signaturesThis check uses npm-compatible registry signatures. It excludes @lpm.dev/* packages and non-registry sources.
Other integrity and provenance checks remain separate.
trust-policy = "no-downgrade" rejects weaker publisher evidence, including downgrades from verified history in the lockfile.
Verification exceptions do not bypass that policy.
--unverified-provenance skips cryptographic verification for a package.
--ignore-provenance-drift skips publisher-identity drift checks. These are different controls, and both can require approval.
See Provenance and trust for verification scope and availability policy.
npm firewall
LPM Firewall is optional and requires an eligible LPM.dev Registry account. It requests verdicts for public npm packages while package downloads continue through the configured registry route.
lpm config firewall --set monitor
lpm config firewall --set enforcemonitor reports warnings and allows installation; downloads do not wait for verdicts. enforce holds each package until its verdict arrives and blocks packages with a blocking verdict.
An entitlement failure also stops an enforced install.
See Firewall for npm for authentication, custom policies, and service-failure behavior.
Policy extensions
Local policy extensions can inspect resolved candidates before registry downloads and package links. The same checks apply during lockfile replay and offline installs.
report mode warns and continues. enforce mode stops an install for a blocking verdict.
Direct remote tarball dependencies are unsupported while policy extensions are active.
See lpm policy to configure and inspect extensions.
Post-install security summary
Local source analysis is disabled by default. Enable it with:
lpm config source-analysis --set trueThis enables package-source analysis during extraction and a scan of installed files for the human security summary. The summary does not rely on stored analysis results or upload package source. It shows severity counts and details for Critical findings. Verbose output adds further details and query hints.
Capabilities such as runtime evaluation appear separately. A detected capability alone does not establish malicious behavior.
LPM.dev Registry enrichment is enabled by default for its packages. It sends package names for behavioral and lifecycle metadata, without source bytes, local findings, versions, or local paths. With local analysis disabled, Registry enrichment can still report findings.
lpm config lpm-insights --set false
lpm install --no-security-summary--no-security-summary skips the post-install scan, enrichment, and human report.
It does not disable extraction-time analysis or delete existing analysis caches.
A normal install does not query OSV or include Registry vulnerability and AI findings.
Use lpm audit or audit-after-install for those findings.
Audit after install
Request an informational audit after installation:
lpm install --audit-after-install
lpm install --no-audit-after-installThe default is disabled. Precedence is: CLI flag, LPM_AUDIT_AFTER_INSTALL, user audit-after-install, then the default.
Audit findings never fail the install. Use lpm audit --fail-on=all for an audit that can fail CI.
JavaScript audits include local analysis, OSV findings, and LPM.dev Registry findings. An explicit Swift install uses the fetched Registry metadata without an OSV query or a Swift source scan. It does not discover transitive Swift dependencies.
The summary includes severity counts and every Critical finding.
JSON output includes audit_summary. If a required vulnerability lookup fails, the summary is omitted and the install still succeeds.
An unchanged project can skip this audit. Run the separate audit command to inspect an existing installation.
LPM.dev Registry integrations
Package-published LPM.dev skills
Online installs can extract agent guidance from direct @lpm.dev/* dependencies into .lpm/skills/<package>/.
This feature is enabled by default.
Installs also restore the guidance of packages that lpm add delivered, at the version recorded in lpm-sources.json.
lpm install @lpm.dev/owner.package --no-skills
lpm config lpm-skills --set false
lpm install @lpm.dev/owner.package --skillsThe flags override user configuration for one run. Disabling automatic extraction does not remove existing skill files.
Use lpm skills clean to remove them.
Skills never fail an install. If a release's skills are still under review, did not pass review, cannot be fetched, or would replace locally edited files, the install warns and keeps the skills already in .lpm/skills/. JSON output lists the messages in warnings.
Online installs also restore the managed agent skills that a committed lpm-agent-skills.json records, with their agent links. --no-skills skips this restore. A skill that cannot be restored, or an unreadable record, produces a warning.
Free packages
Available Free releases install without login:
lpm install @lpm.dev/owner.free-packageA stale credential does not block an available Free release. Protected dependencies still require access. See LPM.dev package distribution.
Cached package access
Online installs check access to every resolved @lpm.dev/* dependency, including cached and transitive packages.
A quarantine, removed release, revoked license, or changed membership can stop an install.
If the access check cannot complete, the online install fails.
JSON denials use package_install_denied and identify the package and reason.
Existing downloaded files remain on disk. Offline installs cannot detect changes to registry access.
Allowed deprecated versions show the registry's deprecation message, including on unchanged installs. Lockfiles continue to pin the original package content.
Pool install reports
Successful installs report the resolved @lpm.dev/* dependency graph to LPM.dev Registry.
Failed installs do not create Pool credit. Free packages do not earn Pool credit.
If the registry cannot confirm a report, the command returns pool_attribution_unconfirmed.
Retry the same command to reuse cached packages and resend the report.
See Pool weighting and limits.
Troubleshooting
Interrupted installs
A failed or interrupted package addition restores staged manifest changes and invalidates the install cache. After a forced stop, the next install attempts recovery before it proceeds.
Repeat the original command to complete the addition:
lpm install zodA no-argument install instead uses the restored manifest and repairs incomplete dependency links.
If you changed a staged manifest after interruption, recovery stops to preserve your edits.
The error identifies the backup under .lpm/install-recovery.
Save your edits separately. Restore the matching backup's original manifest, then retry the install. Reapply your edits after recovery succeeds.
Project node_modules path
The project-level node_modules must be a real directory, not a symlink or directory junction.
Each worktree needs its own directory. Package data can still be shared through the global store.
If the command reports Project layout error, use lpm doctor:
lpm doctor --fix
lpm installThe repair removes the project link entry without removing its target or the target's contents.
Newly published versions
If cached metadata cannot satisfy a requested version or range, LPM CLI refreshes that package's metadata once. This applies to npm, custom registries, and LPM.dev Registry. A full cache reset is unnecessary.
Access restrictions and the release-age policy still apply. If the requested version remains unavailable, the install preserves the previous manifest and lockfile.
Publication review
If an LPM.dev Registry package has versions but no available latest release, the install stops before project changes.
If the registry supplies a status, the error reports pending review, manual review, or processing.
For pending review or processing, retry after the review completes.
For manual review, inspect the package page. JSON output uses publication_unavailable.
See lpm publish.
Unavailable locked packages
If a locked artifact is unavailable, mutable and frozen installs both fail without replacing or rewriting the lockfile. For a direct dependency, the error identifies an upgrade command with the dependency's manifest name.
lpm upgrade <manifest-key>For a transitive dependency, update its direct parent or the relevant override in a mutable project. Review and commit the new lockfile before you retry CI.
Windows paths
The package store supports paths longer than the traditional Windows limit of 260 characters. External build tools can have their own limits. A short checkout path can avoid compatibility failures.
Output
Verbose output
lpm install --verboseVerbose output adds timings, lockfile size, and additional security details.
-v prints the CLI version. It is not a verbose alias.
JSON timing diagnostics
lpm install --json
lpm install --json --timing
LPM_TIMING_DETAIL=1 lpm install --json
LPM_TIMING_DETAIL=trace lpm install --jsonOrdinary JSON output omits timing. --timing or LPM_TIMING=1 includes it.
Detailed modes add diagnostic breakdowns. Trace mode also identifies slow packages.
Use detailed fields for performance investigations rather than as a stable production API.
Install JSON includes package and link counts under counts, and peer diagnostics under peer_issues.
A recursive install emits one JSON document with recursive: true, workspace_root, targets, and summary.
Per-target timing measures that target. Aggregate phase work can exceed total elapsed time because targets can overlap.
See Terminal output for output channels and environment variables for diagnostic controls.
Flags
Package selection and saved versions
| Flag | Effect |
|---|---|
-D, --save-dev | Save packages under devDependencies |
--prod, --production | Omit development dependencies from the installed tree |
--omit <dev|optional> | Omit selected dependency types. Accepts comma-separated or repeated values |
--exact | Save the resolved version without a prefix |
--tilde | Save the resolved version with ~ |
--save-prefix <PREFIX> | Select ^, ~, or an empty prefix |
--catalog[=<NAME>] | Save through an existing default or named catalog entry |
-y, --yes | Confirm multi-member additions and select the first eligible Swift target |
Workspace selection
| Flag | Effect |
|---|---|
-r, --recursive | Refresh the owning workspace, including its root |
--no-recursive | Install only the current project |
--workspace-concurrency <N> | Set the maximum concurrent workspace installs. N must be positive |
--filter <EXPR> | Select workspace members. Repeatable |
--filter-prod <EXPR> | Select members without development edges in dependency closures. Repeatable |
--changed-files-ignore-pattern <GLOB> | Ignore matching paths in Git-based filters. Repeatable |
--test-pattern <GLOB> | Treat matching paths as tests for Git-based dependent selection. Repeatable |
-w, --workspace-root | Add packages to the workspace root |
--fail-if-no-match | Fail if no workspace member matches |
Install behavior
| Flag | Effect |
|---|---|
--offline | Replay the lockfile and store without network requests. Rejects package arguments |
--frozen-lockfile | Require a matching lockfile without changes to either lockfile |
--no-frozen-lockfile | Disable automatic frozen mode in CI |
--force | Resolve, download, and link again. Cannot combine with frozen mode |
--linker <isolated|hoisted> | Override the package layout for this run |
--strict-peer-dependencies | Fail on missing required peers, mismatches, or conflicting peer requirements |
--no-strict-peer-dependencies | Use peer warnings instead of strict failures |
--no-engine-strict | Use warning-only project and dependency engine checks |
--strict-integrity | Reject registry packages without integrity metadata and new remote tarball dependencies without declared SRI |
Registry packages need dist.integrity or dist.shasum. Remote tarball dependencies need declared SRI on first use.
Existing locked integrity remains authoritative.
For checks of reused store files, see lpm config integrity.
Script and security policy
| Flag | Effect |
|---|---|
--policy <deny|allow|triage> | Override dependency script policy |
--yolo | Alias for --policy=allow |
--triage | Alias for --policy=triage |
--advisor <none|claude-cli|codex|ollama> | Override the advisor under triage policy |
--auto-build | Run eligible trusted dependency scripts after installation |
--strict-sandbox | Require strict containment for dependency scripts |
--paranoid | Alias for --strict-sandbox |
--no-sandbox | Remove containment for dependency scripts |
--allow-new | Bypass the minimum release age for this run |
--min-release-age <DUR> | Set a cooldown in minutes (10m), hours (1h), days (1d), or seconds. 0 disables it |
--min-release-age-exclude <SELECTOR> | Exempt a package, exact version, or scope pattern. Repeatable |
--unverified-provenance <PKG> | Skip cryptographic provenance verification for a package. Repeatable |
--unverified-provenance-all | Skip cryptographic provenance verification for all packages |
--ignore-provenance-drift <PKG> | Skip publisher-identity drift checks for a package. Repeatable |
--ignore-provenance-drift-all | Skip publisher-identity drift checks for all packages |
Security exceptions remain subject to approval requirements.
Optional work and diagnostics
| Flag | Effect |
|---|---|
--skills | Enable automatic LPM.dev package skills for this run |
--no-skills | Skip automatic LPM.dev package skills and the restore of recorded agent skills for this run |
--no-security-summary | Skip the post-install source scan, Registry enrichment, and human report |
--audit-after-install | Add an informational audit summary |
--no-audit-after-install | Skip that audit, overriding environment and user configuration |
--timing | Include timing diagnostics in JSON output |
Global packages
| Flag | Effect |
|---|---|
-g, --global | Install one executable package globally |
--replace-bin <CMD> | Transfer a colliding command name to this global package. Repeatable |
--alias <ORIG=ALIAS> | Rename a declared global executable. Accepts repeated or comma-separated mappings |
See global-install restrictions.
The global flags include --json, --verbose, --registry, --token, --insecure, and --color.
See also
lpm uninstall— remove a dependencylpm upgrade— update dependency versionslpm fetch— populate the store from a lockfilelpm rebuild— run approved dependency scriptslpm approve-scripts— review blocked scripts- Workspaces — select and manage workspace members
- Lockfiles — understand the authoritative TOML graph
- Registries — use npm, LPM.dev Registry, and private registries