LPM CLI

lpm resolve

Resolve package specs, inspect exact dependency and peer targets, and report peer issues without installing.

Use lpm resolve to inspect candidate versions and their dependency graphs before you change a project.

lpm resolve [OPTIONS] [PACKAGES]...

At least one package spec is required. The command supports a human-readable tree and JSON output.

Quickstart

# Inspect a candidate version and its dependencies
lpm resolve express@^5

# Resolve related packages together
lpm resolve react@^19 react-dom@^19

# Save a non-interactive result for analysis
lpm resolve express@^5 --json > candidate-graph.json

The command reads registry metadata. It does not download package archives, install packages, or run scripts. It leaves project manifests, lockfiles, and node_modules unchanged. Registry metadata caches can change.

Add a repeatable task

lpm.json has no dedicated resolve configuration. Use an uncached task to repeat a candidate check:

lpm.json
{
  "tasks": {
    "check-candidates": {
      "command": "lpm resolve react@^19 react-dom@^19",
      "cache": false
    }
  }
}
lpm run check-candidates
lpm run check-candidates -- --json

cache: false runs the command each time. Registry metadata caches still apply. An explicit task command takes precedence over a package script with the same name. See Tasks for task options.

Package specs and aliases

lpm resolve react
lpm resolve react@19.2.4
lpm resolve 'react@^19'
lpm resolve react@next
lpm resolve @my-co/internal@^2
lpm resolve react-previous@npm:react@^18 react@^19
SpecMeaning
react or react@*A wildcard request, with a preference for a compatible latest version.
react@19.2.4An exact version.
react@^19A semver range.
react@nextA registry dist-tag.
@my-co/internal@^2A scoped package and range.
react-previous@npm:react@^18A local alias for another package.

The default resolver excludes prereleases from bare wildcard requests. With LPM_RESOLVER=pubgrub, wildcard requests can select prereleases.

Repeated requests with the same local name and range produce one root. A bare name and @* count as the same request. Different ranges or alias targets under one local name cause an error before registry requests.

# Use separate aliases to compare two versions
lpm resolve react-old@npm:react@^18 react-new@npm:react@^19

Registries and project scope

LPM CLI supports npm, LPM.dev Registry, and private registries:

  • @lpm.dev/* always uses LPM.dev Registry.
  • Other scoped packages follow their .npmrc registry mappings.
  • Unscoped packages use the configured default registry, or npm when no override exists.
  • Aliases follow the target package's registry mapping.

See Registry configuration for authentication and routing.

Resolve uses the supplied specs and default resolution policies. It does not load project dependency declarations, catalogs, overrides, or peer rules as install inputs. A later lpm install can select a different graph because project settings and install checks also apply.

For an existing project graph, use lpm graph. For a locked graph, lpm fetch downloads its packages into the store.

Read the tree

Each row shows a package name, version, and node ID. Alias rows also show their local names. Dependency edges and peer edges retain their exact targets, including separate nodes with the same name and version.

app@1.0.0 [#1]
  ├─ helper-alias → helper@2.0.0 [#2]
  └─ host@3.0.0 [#3] (peer)
MarkerMeaning
[#N]Node ID within this result.
(peer)A resolved peer binding.
(shared)This node already appeared. Its children are not repeated.
(circular)This edge returns to a node on the current path.
(depth limit; use --json)This branch reached the tree's depth limit.

The tree has limits of 128 edge levels, 10,000 rows, and 2 MiB of output. A truncation marker identifies the row or byte limit. JSON includes the complete graph without these display limits. Node IDs are local to one result. They are not lockfile IDs or stable identifiers across separate runs.

Peer diagnostics

lpm resolve react@^19 react-dom@^19 --json | jq '.peer_issues'

The default resolver can add required peer packages automatically. If incompatible peer ranges require a best-effort choice, the result includes the selected version and unsatisfied consumers. With LPM_RESOLVER=pubgrub, absent required peers can remain as warnings because that mode does not automatically add them.

Human output shows peer warnings. JSON separates missing peers, incompatible versions, and conflicts. An absent optional peer stays quiet. An optional peer with an incompatible available version can produce a warning. Exact peer bindings take precedence over unrelated matching versions elsewhere in the graph.

Peer warnings do not make a successful resolution fail. If no published version can satisfy a required peer, resolution can fail with a structured error.

# Fail a CI step when a successful resolution still reports peer issues
lpm resolve react@^19 react-dom@^19 --json > resolved.json
jq -e '.success and (.peer_issues.total_count == 0)' resolved.json

The counts describe diagnostic records. One conflict and its version warning can both contribute to total_count.

JSON output

lpm resolve is-number@7.0.0 --json
{
  "success": true,
  "packages": [
    {
      "id": 1,
      "package": "is-number",
      "version": "7.0.0",
      "context": null,
      "dependencies": {},
      "peers": {}
    }
  ],
  "roots": [{ "name": "is-number", "target": 1 }],
  "ambient_peer_installs": [],
  "peer_issues": {
    "missing": [],
    "bad": [],
    "conflicts": [],
    "intersections": [],
    "missing_count": 0,
    "bad_count": 0,
    "conflicts_count": 0,
    "intersections_count": 0,
    "total_count": 0
  },
  "count": 1,
  "elapsed_secs": 0.04
}
FieldMeaning
packages[].idExact node ID within this result.
packages[].packageCanonical registry package name, without context text.
packages[].versionSelected version.
packages[].contextResolution context, or null. Use the node ID for graph joins.
packages[].dependenciesLocal dependency names mapped to exact target IDs.
packages[].peersLocal peer names mapped to exact provider IDs. An unbound peer has no entry.
rootsRequested local names and target IDs, in argument order after duplicate removal.
ambient_peer_installsNames of automatically added peer packages. These names do not identify exact nodes.
peer_issuesDiagnostic arrays and counts. intersections is empty for this command.
countNumber of resolved nodes, including separate contexts for the same package.
elapsed_secsElapsed time through resolution and peer checks, before output.

Every dependency, peer, and root target references an entry in packages. For scripts, join records by ID instead of package name and version.

# List selected versions
lpm resolve express@^5 --json | jq -r '.packages[] | "\(.package)@\(.version)"'

# Inspect requested roots
lpm resolve react@^19 react-dom@^19 --json | jq '.roots'

To inspect an archive and its integrity hash, use lpm download with an exact selected version.

Flags

Resolve has no command-specific flags. These global flags apply:

FlagEffect
--jsonWrite the graph and diagnostics as JSON.
--registry <REGISTRY>Select the LPM.dev Registry endpoint. .npmrc controls npm and private registry routing.
--token <TOKEN>Supply a token for the selected LPM.dev Registry endpoint.

See also