Managed runtimes
How LPM detects, installs, and exposes managed Node.js and Bun runtimes.
LPM manages project runtimes itself. It detects the versions your project asks for, downloads missing installs on demand, stores them under ~/.lpm/runtimes/, and prepends the right bin/ directories to PATH for every script you run.
Node and Bun are supported managed runtimes. Deno is still unsupported.
Detection Order
When lpm run, lpm dev, lpm exec, lpm test, or lpm bench starts, LPM resolves managed runtime pins in deterministic order: Node first, then Bun.
Node
| Priority | Source | Format |
|---|---|---|
| 1 | lpm.json > runtime.node | Semver: ">=22.0.0", "22.5.0", "22" |
| 2 | package.json > engines.node | Semver |
| 3 | .nvmrc | Plain version: 22.5.0, lts/iron, v22 |
| 4 | .node-version | Plain version |
| (fallback) | None of the above | Use the system node from PATH — no managed runtime |
.nvmrc lives in this list intentionally — projects migrating from nvm get Node pinning for free without writing lpm.json. New projects should prefer lpm.json > runtime.node because it sits next to the rest of the LPM config.
Bun
| Priority | Source | Format |
|---|---|---|
| 1 | lpm.json > runtime.bun | Exact, latest, v1.3.14, bun-v1.3.14, prefix, or range |
| (fallback) | No runtime.bun declared | Do not prepend managed Bun |
package.json > engines.bun is recognized as a compatibility warning, but LPM does not enforce it and does not use it as a managed-runtime pin. Use lpm.json > runtime.bun when scripts need Bun available.
Auto-Install
If a detected version is not already installed, LPM downloads it before running the script unless auto-install is disabled:
LPM_NO_AUTO_INSTALL=true lpm devLPM_NO_AUTO_INSTALL=true applies to both Node and Bun. When auto-install is off and a managed runtime is missing, LPM warns and leaves the system PATH in place for that runtime.
Node releases come from https://nodejs.org/dist/index.json, cached for 1 hour at ~/.lpm/runtimes/index-cache.json. Downloads are SHA-256 verified against the matching SHASUMS256.txt entry.
Bun releases come from the GitHub releases API for oven-sh/bun, cached for 1 hour at ~/.lpm/runtimes/bun-index-cache.json. Downloads use Bun's platform asset names such as darwin-aarch64, linux-x64-musl, linux-x64-baseline, and windows-x64. Downloads are SHA-256 verified against GitHub asset digests and/or SHASUMS256.txt; when both are present, both must verify.
Storage Layout
~/.lpm/runtimes/
├── node/
│ └── 22.12.0/
│ └── bin/
│ ├── node
│ ├── npm
│ └── npx
├── bun/
│ └── 1.3.14/
│ └── bin/
│ └── bun
├── index-cache.json
└── bun-index-cache.jsonEach version is installed once and reused by every project on the machine. LPM_HOME=<path> moves the entire LPM root, including runtimes/, which is useful for hermetic CI.
Script PATH Order
When a script runs, LPM builds PATH from:
- Project-local
node_modules/.bin/ - Managed Node
bin/, if a Node pin resolves to an installed version - Managed Bun
bin/, ifruntime.bunresolves to an installed version - The inherited
PATH
This means locally-installed CLIs win over managed runtime tools, and managed Node wins over managed Bun when both provide a command with the same name.
runtime.bun only exposes bun to scripts. It does not switch LPM script execution to bun run.
Node Engine Enforcement
engines.node plays two roles. As a detection source it tells LPM which managed Node runtime to install for lpm dev / lpm run when runtime.node is absent. As an enforcement constraint it gates lpm install / lpm rebuild / lpm add — the pipeline aborts with a structured error if the effective Node version does not satisfy the range.
$ lpm install
Error: lpm::engine_mismatch
× node version 18.20.4 does not satisfy required >=22.0.0 (from package.json
│ > engines.node (compared against system PATH))Resolution: install the matching managed runtime first (lpm use node@22), or relax the constraint.
engines.bun is not enforced in this first Bun runtime pass. Put the desired Bun version in lpm.json > runtime.bun to manage Bun availability.
lpm use
lpm use node@22 # install the latest 22.x, pin in lpm.json
lpm use node@lts # install latest Node LTS
lpm use bun@1.3.14 # install + pin Bun
lpm use bun@latest # install + pin latest Bun
lpm use --list bun # list installed Bun versions
lpm use remove bun@1.3 # remove all installed 1.3.x Bun runtimeslpm use <runtime>@<spec> writes the resolved version into lpm.json > runtime.<runtime>.
During a fresh install, the human output shows the resolved version, downloaded size, SHA-256 verification, extraction/linking, final runtime, and PATH hint.
lpm use <runtime>@<spec> --pin skips the download step. If the spec already matches an installed runtime, LPM writes that exact installed version; otherwise it records the requested spec unchanged so a later lpm dev / lpm run can resolve or auto-install it.
lpm use remove <runtime>@<spec> deletes installed managed runtimes matching the spec without changing lpm.json. If the project still pins a matching runtime, LPM warns because later commands can auto-install it again.
Compatibility With nvm / fnm
LPM's Node management is independent. If you have nvm or fnm installed:
- They modify
PATHin your shell, affectingnodelookup outside LPM. - LPM's Node detection respects
.nvmrc, so a project pinned vianvmworks under LPM without converting. - When LPM runs a script with a managed Node pin, LPM's runtime takes precedence over whatever
nvmset in the shell.
You do not have to remove nvm to adopt LPM. If a project has both .nvmrc and lpm.json > runtime.node, the lpm.json value wins.
See Also
lpm use— install + pin commandlpm.jsonruntime — config field reference- Environment variables —
LPM_NO_AUTO_INSTALL lpm dev— picks up runtime pins automaticallylpm doctor— checks managed runtime state