npm compatibility
Use npm packages and scripts with LPM CLI, and account for differences in installation, trust, and configuration.
LPM CLI uses package.json, npm package metadata, and node_modules. You can install from npm, LPM.dev Registry, or private registries.
# Install the current project
lpm install
# Add a dependency
lpm install zod
lpm install typescript --save-dev
# Run a package script
lpm run test
# Require the committed dependency graph in CI
lpm install --frozen-lockfileThe CLI is registry-agnostic. Only @lpm.dev/* packages always route through LPM.dev Registry. Other packages follow the registry configuration.
Common command equivalents
| npm workflow | LPM CLI workflow |
|---|---|
npm install | lpm install |
npm install <pkg> or npm add <pkg> | lpm install <pkg> |
npm install -D <pkg> | lpm install --save-dev <pkg> |
npm ci | lpm install --frozen-lockfile |
npm uninstall <pkg> | lpm uninstall <pkg> |
npm run <script> | lpm run <script> |
npm outdated | lpm outdated |
npm update | lpm upgrade |
npm audit | lpm audit |
npm publish | lpm publish |
lpm add is a separate source-delivery workflow. Use lpm install to add a normal dependency.
If a script name conflicts with a built-in command, the built-in command takes precedence. Use lpm run explicitly for predictable script selection.
Project files
| Surface | Supported behavior |
|---|---|
dependencies, devDependencies, optionalDependencies, peerDependencies | Read from package.json. Optional declarations take precedence over duplicate regular declarations. |
scripts | Shell commands with pre/post hooks through lpm run. |
bin | A string or a map of executable names. |
files | Controls package contents for packing, publishing, and workspace deployment. |
workspaces | Array and object forms. Patterns combine with pnpm-workspace.yaml. |
engines.node, engines.lpm | Compatibility checks against the selected runtime and CLI. |
overrides, resolutions, lpm.overrides | Supported version and path selectors, subject to the limits below. |
catalogs | Shared dependency specifications from the workspace root. |
lpm.json can define tasks and publish defaults. It does not replace package.json dependency declarations.
See workspaces, catalogs, and package configuration.
Versions and overrides
The resolver accepts npm ranges, wildcards, hyphen ranges, unions, prereleases, aliases, and distribution tags such as latest and beta.
A new bare package request normally saves ^resolvedVersion. Existing specifications, source dependencies, save flags, and catalogs can change that result. See save policy.
Overrides accept supported package selectors and string values. Nested npm override objects are ignored with a warning. npm $dependency references and replacement aliases are not supported override values.
lpm.overrides takes precedence over matching npm overrides and Yarn resolutions. See resolver overrides for exact selectors and precedence.
Registry configuration
.npmrc supplies registry routing, credentials, and supported TLS options. It does not apply every npm setting to LPM CLI.
registry=https://registry.npmjs.org/
@my-team:registry=https://packages.example.com/
//packages.example.com/:_authToken=${NPM_TOKEN}Supported credentials include bearer tokens, encoded Basic authentication, and username/password pairs. TLS configuration includes additional certificate authorities and client certificates.
Use the .npmrc reference for accepted keys, file precedence, credential scope, and security restrictions.
Script execution
lpm run runs pre<script>, the selected script, then post<script>. A failed phase stops later phases.
A single requested task with no task dependencies preserves the child exit code. Root install failures also preserve that code.
Multiple tasks return the number of failed tasks. Workspace runs and dependency rebuilds report failure for the whole operation.
Each script phase receives its own npm context:
| Variable | Value |
|---|---|
npm_lifecycle_event | The current phase name. |
npm_lifecycle_script | The declared command, without extra CLI arguments. |
npm_package_name | The current package name, or an empty value if absent. |
npm_package_version | The current package version, or an empty value if absent. |
npm_package_json | The current package's manifest path. |
INIT_CWD | The directory where the command started. |
These values replace inherited values for the same variables. Dependency scripts use the installed dependency's identity and manifest.
Explicit lpm.json task commands use the task name for npm_lifecycle_event. They run directly, without npm pre/post hook lookup.
With --json, script output goes to stderr. Stdout contains one result. Cached output follows the same rule.
A bare root install runs pnpm:devPreinstall before dependency installation. After installation succeeds, it runs preinstall, install, postinstall, preprepare, prepare, and postprepare.
Dependency scripts run through lpm rebuild: preinstall, install, then postinstall. Dependency prepare and uninstall hooks do not run.
With the default store, dependency scripts first find tools from their own dependencies and peers. Project tools and the inherited PATH follow.
Dependencies that need lifecycle scripts finish before their dependents, including through packages with no scripts. Cyclic dependencies cannot guarantee that order.
LPM CLI does not synthesize an install script from binding.gyp. A native package must declare the required lifecycle command.
Dependency scripts require trust
Dependency lifecycle scripts are denied by default. The root project's install lifecycle remains active.
# Install, then review blocked dependency scripts
lpm install
lpm approve-scripts
# Run approved dependency scripts
lpm rebuildTrusted dependencies and explicit policy settings can permit automatic builds. --policy=allow permits dependency scripts for that install:
lpm install --policy=allowSee install lifecycle behavior, script approval, and rebuild for the trust checks and automation controls.
Dependency layout
Single-package projects default to the hoisted layout. Direct dependencies appear at the project root. Each dependency retains links to its own resolved dependencies.
This layout does not expose every transitive dependency at the root. Workspaces default to isolated mode. Peer conflicts can also select isolated mode automatically.
lpm install --linker=isolated
lpm install --linker=hoistedExplicit configuration overrides automatic layout selection. See dependency layouts.
If application code imports an undeclared package, add that package to the application's dependencies. A different layout does not replace a correct manifest.
Lockfiles and CI
LPM CLI writes authoritative lpm.lock files. Current schema 13 uses TOML only.
# Convert a supported npm, pnpm, Yarn, or Bun lockfile
lpm migrate
# Reject manifest and lockfile mismatches in CI
lpm install --frozen-lockfileCommit lpm.lock. See lockfiles for formats and recovery.
LPM CLI does not generate package-lock.json for tools that require that file. Changing the dependency layout does not provide an npm lockfile.
Engine requirements
LPM CLI enforces supported engines.node and engines.lpm requirements by default. Incompatible required packages fail installation. Incompatible optional-only packages can be skipped.
engines.npm is not an LPM CLI compatibility constraint. Engine requirements do not select or download a runtime.
# Report engine mismatches as warnings for this invocation
lpm install --no-engine-strictUse runtime configuration to select Node. See engine enforcement for persistent configuration.
Other compatibility limits
- Yarn Plug'n'Play files do not replace
node_modules. - Installation does not directly consume
pnpm.overrides,pnpm.patchedDependencies, orpnpm.peerDependencyRules.lpm migratetranslates these fields. - LPM CLI configuration controls script policy, release cooldown, and other install behavior. Equivalent npm settings are not automatically interchangeable.