LPM CLI

lpm fetch

Download locked packages into the store before an offline install or a container build.

Use lpm fetch to prepare the package store from lpm.lock without installing the project.

lpm fetch [--platform OS/ARCH[/LIBC]]

Quickstart

# Download packages for this machine
lpm fetch

# Prepare packages for a Linux container
lpm fetch --platform linux/x64/glibc

# Link the project from the prepared store
lpm install --offline --frozen-lockfile

The command supports non-interactive use. It has one mode: read the lockfile, check applicable packages, and populate the store. It does not resolve versions, change manifests or lockfiles, create node_modules, or run package scripts. A package.json file is not required.

Add a repeatable task

lpm.json has no dedicated fetch configuration. Use an uncached task:

lpm.json
{
  "tasks": {
    "fetch-packages": {
      "command": "lpm fetch",
      "cache": false
    }
  }
}
lpm run fetch-packages
lpm run fetch-packages -- --platform linux/arm64/musl --json

The command checks the store on every run. The task does not reuse a previous task result. An explicit task command takes precedence over a package script with the same name. See Tasks for task configuration.

Prepare a container layer

After the container has LPM CLI, separate package downloads from source changes:

COPY lpm.lock ./
RUN lpm fetch --platform linux/x64/glibc

COPY . .
RUN lpm install --offline --frozen-lockfile --prod

Keep the same store available for both commands. Private registries also need their registry configuration and credentials during fetch. The later install checks that the project matches the lockfile, then creates node_modules from the store. Local dependencies need their files in the checkout before that install.

Lockfile and workspace scope

Fetch uses the authoritative lpm.lock. It considers every saved package instance, including dependencies from all recorded workspace members. A workspace root without its own dependencies still fetches member dependencies. From a member directory, the owning workspace lockfile takes precedence over a stale member lockfile.

A directory that contains only lpm.lock also works, even under an unrelated project directory. Fetch does not need workspace manifests to read the saved package graph. It does not add packages that the lockfile omits.

Package sources and integrity

LPM CLI supports npm, LPM.dev Registry, and private registries. Fetch uses locked tarball URLs and registry routing. It does not request newer versions.

SourceBehavior
Registry packageDownload the locked tarball with the applicable registry authentication.
Remote tarball URLDownload the locked HTTP or HTTPS URL without registry bearer credentials.
Commit-pinned GitHub packageDownload the archive for the saved commit.
Local directory, link, or tarballSkip it. The later install reads the local source.

Each applicable remote entry needs an SRI integrity hash. Registry entries also need a tarball URL. Missing integrity and downloaded bytes that do not match the hash cause errors. Fetch has no option to bypass these checks.

GitHub sources must identify an exact commit. Other Git hosts and transports are unsupported. GitHub downloads reject redirects and URLs that contain credentials. Packages receive source analysis before they enter the store.

Repeated package instances can share one archive download. The result still includes each lockfile instance. Existing reusable store objects count as cached.

Recover from stale or missing lockfile data

If an entry lacks integrity or a required URL, refresh the lockfile in the complete project:

lpm install
lpm fetch

The legacy v1 store identifies registry packages by name and version. If those coordinates contain different bytes, fetch reports an integrity conflict and preserves the existing entry. Use the default v2 store for that run:

LPM_STORE_VERSION=v2 lpm fetch

See Store configuration for store versions and locations.

Platform selection

By default, fetch uses the current machine's operating system, CPU, and detected libc. Use --platform to prepare another target:

lpm fetch --platform linux/x64/glibc
lpm fetch --platform linux/arm64/musl
lpm fetch --platform darwin/arm64
lpm fetch --platform win32/x64

Filters use the lockfile's os, cpu, and libc fields. An empty field imposes no restriction. A sole any entry accepts all known values. An exclusion such as !win32 wins over a positive match. A list with positive and negative entries still requires a positive match.

An explicit target without its third component has no libc value. It does not inherit the host libc. Packages with libc restrictions are skipped for that target, including a libc field that contains any. For Linux containers, include glibc or musl when the target requires it.

Firewall checks and concurrency

When LPM Firewall is active, fetch checks eligible public npm packages. This includes recognized public npm registry and tarball entries. Private registry packages and arbitrary remote URLs are excluded.

monitor fetches while the check runs, then warns and continues. enforce finishes the check before cache reuse or downloads, and blocks denied packages or denied entitlement. Active modes require LPM.dev Registry authentication. Use lpm login locally or LPM_TOKEN in CI.

Fetch permits 24 concurrent artifact downloads by default. LPM_CONCURRENT_DOWNLOADS accepts integers from 1 through 256:

LPM_CONCURRENT_DOWNLOADS=8 lpm fetch --json

An invalid value produces a warning and uses the default.

JSON output

lpm fetch --platform linux/x64/glibc --json
{
  "success": true,
  "lockfile": "lpm.lock",
  "platform": { "os": "linux", "cpu": "x64", "libc": "glibc" },
  "counts": { "total": 1, "fetched": 0, "cached": 1, "skipped": 0 },
  "packages": [
    { "name": "react", "version": "19.2.4", "source": "registry", "status": "cached" }
  ],
  "elapsed_ms": 12
}

Counts describe package instances, not HTTP requests. Each status is fetched, cached, or skipped. Skipped rows include a reason: platform, local_source, or local_tarball. An active firewall check can add a firewall object.

Flags

FlagEffect
--platform OS/ARCH[/LIBC]Select the target for package filters.
--jsonWrite the result as JSON.

See Global flags for shared options. --registry configures the client. It does not replace tarball URLs already saved in the lockfile.

See also