Migrating to LPM CLI
Convert an existing npm, pnpm, yarn, or bun project to LPM CLI with one command.
lpm migrate is the one-command path from any npm-ecosystem project to LPM CLI. It auto-detects the source package manager, converts its lockfile to LPM CLI's TOML lockfile (lpm.lock) plus lpm.lockb when the graph fits the binary format, preserves your config, and runs a fresh install to verify nothing broke. Every file it touches is backed up first — lpm migrate --rollback reverts everything.
The migration shape is the same for every source. What differs is the lockfile parser and any source-specific config (most notably pnpm.* blocks → lpm.*).
Sources supported today
| From | Source files | Walkthrough |
|---|---|---|
| npm | package-lock.json | Migrating from npm |
| pnpm | pnpm-lock.yaml (+ pnpm-workspace.yaml, pnpm.* blocks in package.json) | Migrating from pnpm |
| Yarn (classic + Berry) | yarn.lock | Same flow — lpm migrate auto-detects |
| Bun | bun.lock / bun.lockb | Same flow — lpm migrate auto-detects |
The 30-second version
lpm migrate --dry-run # preview: parse the source lockfile, report what'll convert
lpm migrate # do it: convert, install, verifyThat's the whole flow. Each step is backed up; if anything goes wrong, lpm migrate --rollback walks the .backup files and restores the pre-migration state.
What carries over without changes
package.json > dependencies/devDependencies/peerDependencies/optionalDependencies— read identically.package.json > scripts—lpm run <name>and the bare-name shorthand (lpm <name>) work the same asnpm run/pnpm run.package.json > workspaces— both array and object forms accepted. (pnpm-workspace.yamlis also read as a fallback.).npmrc— scope-to-registry mappings and per-origin auth tokens carry over verbatim. LPM CLI honors.npmrcfor routing across npm, LPM.dev Registry, and private registries.package.json > overrides(npm-style) andresolutions(yarn-style) — honored as-is.
What changes — be deliberate
These behave differently than your previous PM:
| Difference | What to do |
|---|---|
Dependency lifecycle scripts deny-by-default. Bare lpm install runs the root project's lifecycle, including prepare, but dependency postinstall scripts stay blocked. | Run lpm rebuild once after migration, then lpm approve-scripts to whitelist packages that need to run scripts. Or set package.json > lpm > scriptPolicy = "allow" for npm-classic dependency-script semantics. |
node_modules layout differs. Single packages start in LPM CLI's v2 hoisted virtual-store layout. Workspaces auto-flip to isolated (pnpm-style symlinks), and default installs with peer conflicts also auto-switch to isolated. | Phantom-dep code (importing a package you didn't declare in dependencies) breaks under isolated. Add the missing entries; or override per-project with package.json > lpm > linker = "hoisted". |
| Cooldown on recent direct versions. LPM CLI blocks direct/root dependency versions published less than 24h ago by default; strict policy can also cover transitives. | lpm install --allow-new per-invocation, or package.json > lpm > minimumReleaseAge / minimumReleaseAgePolicy per-project. |
engines enforced by default. npm reads engines but only enforces with engine-strict=true in .npmrc; LPM CLI also checks selected dependencies' engines.node. | Set package.json > lpm > engineStrict = false for warning-only behavior. |
pnpm.overrides / pnpm.patchedDependencies / pnpm.peerDependencyRules | Auto-translated by lpm migrate to lpm.overrides / lpm.patchedDependencies / lpm.peerDependencyRules. The original pnpm.* blocks stay in place so a parallel pnpm install keeps working during transition. |
After the migration
lpm install --offline # confirms reproducibility from the new lockfile
lpm test # confirms nothing broke under isolated layout / deny-by-default
lpm lint
lpm fmt --checkCommit lpm.lock, lpm.lockb when present, the updated .npmrc, and the (possibly mutated) package.json. Discard the source lockfile (package-lock.json / pnpm-lock.yaml / yarn.lock / bun.lock*) only after everyone on the team has switched over — leaving it in place during transition lets developers keep using the old PM until they cut over.
Walkthroughs
Migrating from npm
package-lock.json → lpm.lock, plus lpm.lockb when representable.
Migrating from pnpm
pnpm-lock.yaml + pnpm.* blocks → LPM CLI equivalents. Isolated layout preserved.
Migrating from Yarn
Yarn Classic or Berry yarn.lock → lpm.lock, with rollback.
Migrating from Bun
bun.lock or bun.lockb → lpm.lock, with rollback.
All paths use the same lpm migrate command and produce the same LPM CLI end state. The per-source guides call out parser-specific details.
See also
lpm migrate— full flag reference (--dry-run,--force,--rollback,--no-install,--skip-verify,--no-npmrc,--ci,--no-ci)- npm compatibility — what carries over, what differs, what LPM CLI adds
- Lockfile — what the lockfile actually pins
- Project setup — where post-migration config lives