LPM CLI

lpx / lpm dlx

Run a package binary without installing it into the project.

lpx [--refresh] [--allow-new] [--min-release-age=<dur>] [--min-release-age-exclude <pkg>] <package> [-- args...]
lpm dlx [--refresh] [--allow-new] [--min-release-age=<dur>] [--min-release-age-exclude <pkg>] <package> [-- args...]

Fetches a package's binary, caches it under ~/.lpm/cache/dlx/, and runs it without touching your project's package.json or node_modules. The LPM CLI equivalent of npx, pnpm dlx, and bunx.

lpx is the short form for lpm dlx; both run the same command.

Examples

lpx cowsay "hello"
lpx dlx cowsay "hello"
lpx create-next-app@latest my-app
lpx prettier --check .
lpx http-server -p 8080
lpx --refresh create-next-app   # bypass the dlx cache
lpx --min-release-age=0 create-next-app@latest
lpx --min-release-age-exclude create-next-app create-next-app@latest

How it works

  1. Resolve the spec. If the package already exists in the caller project's lpm.lock and the locked version satisfies the requested spec, lpx uses that exact version first. Otherwise it resolves against the appropriate registry. lpx calls into the full install pipeline, so routing follows the same rules as lpm install: @lpm.dev/* packages go to LPM.dev Registry, .npmrc-declared scopes go to the registry that scope points at, and everything else goes to registry.npmjs.org.
  2. Materialize the package into a cache directory under ~/.lpm/cache/dlx/. Lockfile-selected entries are keyed by resolved name@version plus integrity; registry-resolved entries keep the requested spec as their cache key. Every run prints the resolved name@version, integrity, and source before executing the binary.
  3. Read the installed package's bin metadata and choose the default executable. If the package exposes exactly one bin, LPM CLI uses it. If it exposes multiple bins, LPM CLI prefers the one matching the package's short name (eslint for eslint, foo for @scope/foo). If there is still no unambiguous default, lpx errors instead of guessing.

lpx <pkg>@<version> pins the requested version. lpx <pkg> prefers the project lockfile when available, then reuses the dlx cache while the cache entry is fresh and auditable. Once the TTL expires, the next run reinstalls against the current resolution of that spec and reports that it is refreshing the expired cache entry.

Cache TTL

dlx cache entries live for 24 hours from install or explicit refresh. After that, the next invocation reinstalls so you don't keep running an old binary forever. Within the TTL window, repeat invocations are essentially free — the cache entry already has node_modules/.bin/ populated and the binary spawns directly.

Cache hits do not extend the TTL. A frequently used dlx entry is still revalidated after 24 hours.

--refresh forces an immediate reinstall regardless of the TTL.

Trust model

Dependency lifecycle scripts under lpx go through the same install policy chain as lpm install: release-age cooldown for the requested package, provenance checks, script policy, trusted dependencies, and sandbox policy are all evaluated by the install pipeline. lpx also carries the caller project's package.json > lpm policy into the temporary install root.

The package binary itself still runs as a third-party command in your project directory. LPM CLI strips common secret-bearing env vars and runtime-hijack env vars before spawn, but you should still treat lpx <pkg> as running arbitrary code from that package.

Argument forwarding

Anything after the package name is forwarded to the binary:

lpx prettier --write src/
# runs: prettier --write src/

Cache management

The dlx cache lives at ~/.lpm/cache/dlx/. Manage it with lpm cache:

lpm cache clean dlx     # drop only the dlx cache
lpm cache path dlx      # print the cache root

Bypass the cache for one invocation with --refresh:

lpx --refresh create-next-app

Flags

FlagEffect
--refreshForce a fresh download, ignoring the dlx cache
--allow-newBypass the minimum-release-age cooldown for this run, subject to the same security approval boundary as install
--min-release-age=<DUR>Override the cooldown window for this run (<N>h, <N>d, <N>m, or seconds; 0 disables), subject to the same security approval boundary as install
--min-release-age-exclude <PKG>Exempt one exact package name from the cooldown for this run; repeatable

Plus the global flags.

See also