LPM CLI

Save policy

Control the versions and catalog references that LPM CLI saves in package.json.

Save policy controls the dependency specifications that lpm install writes to package.json. The lockfile records the selected versions separately.

# Save a new dependency with the default caret range
lpm install zod

# Save the resolved version exactly
lpm install zod --exact

# Preserve an explicit range
lpm install 'zod@~4.3.6'

# Save an existing catalog reference
lpm install --catalog zod

These rules apply to npm, LPM.dev Registry, and private npm-compatible registries. This page covers JavaScript dependencies. Swift requirements follow the Swift package workflow.

What gets saved

For a new dependency, assume that the stable selection is 4.3.6 and the prerelease selection is 4.4.0-beta.2:

InputSaved specification
zod^4.3.6
zod@latest^4.3.6
zod@4.3.64.3.6
zod@^4.3.0^4.3.0
zod@~4.3.6~4.3.6
zod@**
zod@next4.4.0-beta.2
@my-co/shared@workspace:*workspace:*

This table assumes no catalog policy or save override. A workspace: request requires a matching package in the current workspace. Explicit workspace ranges must accept its local version.

Tags such as latest select a version. The saved specification contains that version, not the tag.

Quote arguments that contain shell characters such as *, ^, or >:

lpm install 'zod@*'
lpm install 'zod@>=4.3.0 <5'

--dev selects devDependencies. It does not change the range rules.

Catalogs take precedence

For ordinary registry dependencies, catalog saves and automatic catalog modes run before the direct range rules:

  1. --catalog or --catalog=<name> selects an existing catalog entry.
  2. catalogMode: "prefer" saves a matching default entry as catalog:. A mismatch retains the direct specification and prints a warning.
  3. catalogMode: "strict" requires a matching default entry. A missing entry or version mismatch fails the operation.
package.json
{
  "catalogs": {
    "default": { "zod": "^4.3.0" }
  },
  "lpm": {
    "catalogMode": "prefer"
  }
}
# A matching default entry saves as catalog:, including an explicit version
lpm install zod@4.3.6

For registry dependencies, automatic catalog mode can override explicit version text, save flags, and an existing direct range. The catalog range must still accept the resolved version.

Automatic catalog modes preserve source dependencies, including workspace links, local paths, aliases, Git sources, and tarball URLs. --catalog cannot replace these sources.

The default catalog mode is manual. In the workspace root, set package.json > lpm.catalogMode to manual to stop automatic conversion.

This setting does not replace existing catalog: references during bare reinstalls. There is no one-run catalog-mode override.

--catalog does not create or edit the catalog entry. A failed catalog check restores the manifest. See lpm catalog.

Direct range precedence

When no catalog reference applies, an explicit exact version, range, wildcard, or workspace: specification remains unchanged.

For a new bare dependency or a tag, LPM CLI uses the first applicable rule:

PriorityRule
1--exact, --tilde, or --save-prefix.
2Save a prerelease exactly.
3save-exact = true.
4The configured save-prefix.
5The default caret prefix, ^.
lpm install zod --exact
lpm install zod --tilde
lpm install zod --save-prefix ''
lpm install zod --save-prefix '^'

--exact, --tilde, --save-prefix, and --catalog are mutually exclusive. A save flag does not replace an explicit range:

lpm install 'zod@~4.3.6' --exact
# Saves ~4.3.6

Persistent defaults

Set project defaults beside the installation's package.json:

lpm.toml
save-prefix = "~"
save-exact = false

When you add packages in a workspace, LPM CLI reads the workspace root's lpm.toml.

Set user defaults through lpm config:

lpm config set save-prefix '~'
lpm config set save-exact false

Each project key overrides the corresponding user key in ~/.lpm/config.toml. Missing keys inherit their user value. LPM_HOME changes the user configuration directory.

KeyRecommended valuesDefault
save-prefix"^", "~", or """^"
save-exacttrue or falsefalse

The loader also accepts quoted boolean values: "true", "false", "1", "0", "yes", and "no".

save-exact = true takes precedence over the configured prefix. To replace a global exact policy with a project tilde policy, set both keys as shown.

lpm.json and package.json > lpm do not define these two keys. Catalog mode is a separate manifest setting.

Invalid values fail with the configuration file path. * is not a valid default prefix. Request a wildcard for a specific package instead.

Existing dependencies

A bare reinstall preserves an existing specification in the selected dependency section when no save flag or catalog conversion applies:

# Existing dependency: "zod": "~4.3.6"
lpm install zod
# Still ~4.3.6

For an ordinary registry dependency, a save flag requests a rewrite of a bare dependency:

lpm install zod --exact

Save flags preserve an existing source specification during a bare reinstall. They also preserve a catalog reference whose entry identifies a source.

Changing persistent defaults alone does not rewrite every existing dependency. An install without package arguments also does not apply a new prefix across the manifest.

Prereleases

A tag that selects a prerelease saves the exact version by default:

lpm install zod@next
# Example: 4.4.0-beta.2

The range ^4.4.0-beta.2 accepts later prereleases of 4.4.0. It also accepts stable versions from 4.4.0 up to, but excluding, 5.0.0. It excludes prereleases of other version tuples, such as 4.5.0-beta.1.

Use a CLI override to request that range:

lpm install zod@next --save-prefix '^'

Without catalog conversion, an explicit prerelease range remains unchanged. Persistent prefix settings alone do not widen a newly resolved prerelease.

Source dependencies

Explicit workspace: arguments are supported:

lpm install '@my-co/shared@workspace:*'

Declare other source dependencies in package.json, then run lpm install:

package.json
{
  "dependencies": {
    "shared": "file:../shared",
    "compat": "npm:actual-package@^2.0.0"
  }
}
lpm install

Package arguments with alias, Git, local-path, or tarball version tokens fail before installation. LPM CLI does not interpret these source tokens as registry tags.

A bare reinstall preserves existing source declarations, including names under @lpm.dev/. If selected workspace targets mix a source dependency and a Swift registry package, install those target groups separately.

Repeated package arguments

Identical requests for the same local package name are processed once. Different requests for that name fail before manifest changes:

lpm install zod zod

# Conflicting requests: choose one specification
lpm install zod zod@4.3.6

See also