# Compared to npm, pnpm, bun (/docs/comparison)





A factual comparison of default behavior across **npm**, **pnpm**, **bun**, and **lpm**.

## Benchmarks [#benchmarks]

Install benchmarks use the tracked VitePress docs fixture, a real-world workspace graph with 535 packages.

| Benchmark                     |      npm |    pnpm |     bun |   **lpm** | **lpm + LPM Firewall monitor** |
| ----------------------------- | -------: | ------: | ------: | --------: | -----------------------------: |
| Cold install, equal footing ¹ | 17,354ms | 6,125ms | 2,455ms |   2,945ms |                        3,043ms |
| Warm install ¹                |  3,819ms | 3,301ms |   451ms | **387ms** |                      **324ms** |
| Up-to-date install ¹          |    282ms |   522ms |    77ms |  **14ms** |                       **14ms** |

Dev command benchmarks measure already-installed local scripts, local bins, and built-in tools.

| Benchmark                        | npm / npx / tsx |  pnpm | bun / bunx |  **lpm** |
| -------------------------------- | --------------: | ----: | ---------: | -------: |
| Trivial echo script ²            |            74ms | 161ms |       15ms | **10ms** |
| Node startup + tiny script ²     |           101ms | 185ms |       33ms | **27ms** |
| Local bin: `esbuild --version` ² |           144ms | 174ms |       27ms | **21ms** |
| Run TSX app, warm cache ³        |           112ms |     — |       19ms | **41ms** |
| `lpm lint` vs `npx oxlint` ⁴     |           273ms |     — |          — |  **3ms** |
| `lpm fmt` vs `npx biome` ⁴       |           340ms |     — |          — |  **3ms** |

<Accordions>
  <Accordion title="What each row measures">
    All displayed values are medians across 10 measured runs. The dated raw result artifacts are linked with each benchmark group below.

    **Cold install** — a fresh project with no package-manager cache, lockfile, or `node_modules/`; cleanup happens outside the timer. [Install results — July 10, 2026](https://github.com/lpm-dev/rust-client/blob/main/bench/perf-results/readme-install-vitepress-20260710T140139.md).

    **Warm install** — cache and lockfile already exist, so the package manager rebuilds `node_modules/`.

    **Up-to-date install** — nothing changed, so the package manager checks state and exits.

    **Trivial echo script** — the cost of invoking an already-installed `package.json` script that runs `echo hi` through each package manager. [Script and local-bin results — July 10, 2026](https://github.com/lpm-dev/rust-client/blob/main/bench/perf-results/readme-run-bin-20260710T214708Z.md).

    **Node startup + tiny script** — the cost of invoking an already-installed `package.json` script that starts Node and performs a tiny stdout write.

    **Local bin row** — the cost of invoking an already-installed `node_modules/.bin` entry.

    **Run TSX app** — warm-cache execution of a generated 10-module TSX ESM app. [TSX results — July 10, 2026](https://github.com/lpm-dev/rust-client/blob/main/bench/perf-results/readme-exec-runtime-20260710T141510.md).

    **Managed tools** — `lpm lint` and `lpm fmt` use cached managed tools instead of paying `npx` resolution overhead. [Built-in tool results — July 11, 2026](https://github.com/lpm-dev/rust-client/blob/main/bench/perf-results/readme-builtin-tools-20260711T205110Z.md).
  </Accordion>

  <Accordion title="Methodology">
    **¹ Install benchmarks** — Generated by `bench/scripts/run-install-readiness.mjs` with `--samples 10 --fixtures vitepress --managers lpm,bun,pnpm,npm --modes cold,warm,up-to-date --lpm-firewall-modes off,report`. Each run uses an isolated temporary project, `HOME`, package-manager cache, and `LPM_HOME`; samples are round-robin interleaved to reduce live-network bias. Dependency lifecycle scripts are disabled for all package managers.

    **LPM Firewall monitor mode** — The LPM Firewall monitor column runs the same LPM CLI install with `LPM_NPM_FIREWALL=report`. In the cold install row, LPM CLI checked 535 package versions before materializing package bytes.

    **² Script and local-bin benchmarks** — Generated by `bench/scripts/run-bin-benchmark.mjs` with 10 measured iterations after 2 warmups. Dependency installation is setup-only and not timed. Tool versions: `lpm 0.67.0`, `npm 10.9.4`, `npx 10.9.4`, `pnpm 11.3.0`, `bun 1.3.14`, `bunx 1.3.14`.

    **³ TSX benchmark** — Generated by `bench/scripts/exec-runtime-benchmark.mjs` against a generated 10-module TSX ESM app with 10 measured iterations after 2 warmups. The `npm / npx / tsx` column is `tsx`; the `bun / bunx` column is `bun`.

    **⁴ Built-in tool benchmarks** — Generated with `RUNS=10 LPM_BIN=target/release/lpm-rs BENCH_WORK_DIR=/tmp/lpm-readme-builtin-tools-work-20260711T205110Z ./bench/run.sh builtin-tools`. [Raw artifact — July 11, 2026](https://github.com/lpm-dev/rust-client/blob/main/bench/perf-results/readme-builtin-tools-20260711T205110Z.md).
  </Accordion>
</Accordions>

## Security defaults [#security-defaults]

| Axis                                                                                                                | npm                                    | pnpm                                                                             | bun                                                                                                                                    | lpm                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Dependency lifecycle-script sandbox](/docs/packages/install#sandbox)                                               | —                                      | —                                                                                | —                                                                                                                                      | **Dependency lifecycle-script sandbox:** approved or triage-selected dependency scripts run under macOS Seatbelt, Linux Landlock, or Windows AppContainer. Default mode contains filesystem access while allowing network. Strict mode denies outbound network on macOS and AppContainer; Linux 6.7+ uses Landlock V4 plus seccomp, with AF\_UNIX retained for IPC. Older Linux kernels and Windows installs missing the AppContainer helper refuse strict mode unless `allow-degraded = true`. Root-project lifecycle scripts are not sandboxed. |
| [Dependency lifecycle scripts (`preinstall` / `install` / `postinstall`)](/docs/packages/approve-scripts)           | All scripts run                        | Blocked until approved (`approve-builds` flow)                                   | Blocked unless in `trustedDependencies`; bun ships a built-in 367-package default trusted list that also runs scripts without approval | Dependencies are blocked by default. Under the opt-in `triage` policy, green verdicts are eligible to auto-run in the sandbox; an optional advisor can approve amber verdicts for the current run; red verdicts remain blocked. The root project's lifecycle runs on bare `lpm install` without the dependency sandbox.                                                                                                                                                                                                                           |
| [Registry package signatures](/docs/packages/audit#registry-signatures)                                             | Manual via `npm audit signatures`      | Manual via `pnpm audit signatures`                                               | —                                                                                                                                      | `lpm audit signatures`; optional install-time fail-closed verification with `lpm config signatures --set true`                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| [Sigstore provenance verification](/docs/packages/security-audit#layer-4-provenance--cooldown)                      | Publish-time provenance support        | Publish-time provenance support                                                  | —                                                                                                                                      | DSSE + Rekor body + Rekor SET + SCT + X.509 chain verified end-to-end on install for provenance bundles served by npmjs                                                                                                                                                                                                                                                                                                                                                                                                                           |
| [Minimum release age (cooldown)](/docs/packages/install#recently-published-packages)                                | `min-release-age` flag, off by default | 1-day cooldown by default                                                        | Off by default                                                                                                                         | 1-day direct/root cooldown by default; strict transitive policy opt-in                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| [`engines.node` enforcement](/docs/packages/install#engines-enforcement)                                            | Warn only                              | Warn only                                                                        | —                                                                                                                                      | When an effective Node version is available, hard-fails incompatible required root/dependency constraints, skips optional-only incompatible packages, persists dependency constraints for warm/frozen/offline replay, and supports warning-only opt-out                                                                                                                                                                                                                                                                                           |
| [Built-in vulnerability audit](/docs/packages/audit)                                                                | npm security database                  | Registry-side data                                                               | Proxies to npm audit endpoint                                                                                                          | OSV + behavioral analysis + verdict cache                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| [Approval-gated weakening of security posture](/docs/infra/security)                                                | —                                      | —                                                                                | —                                                                                                                                      | Weaker CLI flags can require native approval; pulled repo or config-file weakenings are treated as proposals until a short-lived unlock or persistent signed machine approval exists                                                                                                                                                                                                                                                                                                                                                              |
| [Provenance drift detection on republish](/docs/packages/security-audit#layer-4-provenance--cooldown)               | —                                      | Resolve-time trust-rank downgrade refusal (trustedPublisher → provenance → none) | —                                                                                                                                      | Detects publisher-identity drift for stored rich trust bindings; optional `trust-policy = "no-downgrade"` refuses weaker npm publish trust during resolution and requires continued artifact verification after verified lockfile history                                                                                                                                                                                                                                                                                                         |
| Pluggable third-party security scanner protocol (register an npm package as a scanner, run it against the lockfile) | —                                      | —                                                                                | `bunfig.toml > [install.security] scanner = "<pkg>"`, invoked by `bun pm scan`                                                         | — (built-in triage + audit cover a different surface; not pluggable)                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |

## Resolver, store, and layout [#resolver-store-and-layout]

| Axis                                                                                | npm                                | pnpm                                               | bun                                                                 | lpm                                                                                                                                                                                                           |
| ----------------------------------------------------------------------------------- | ---------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Resolver](/docs/packages/resolver)                                                 | Arborist backtracking              | Highest-version + workspace-rooted peer resolution | Tree resolution + backtracking                                      | Greedy-fusion (PubGrub legacy arm available)                                                                                                                                                                  |
| [Package store](/docs/packages/content-addressable-store)                           | Content-addressable cache          | Content-addressable, versioned virtual store       | Content-addressable, hardlinked                                     | Content-addressable; prefers APFS clonefile on macOS, with hardlink/copy fallback                                                                                                                             |
| [`node_modules` layout](/docs/packages/install#how-it-works)                        | Hoisted                            | **Isolated** (symlinked virtual store)             | Auto: hoisted for single-package, isolated when workspaces detected | Auto: v2 hoisted virtual-store for single packages, isolated for workspaces or default peer-conflict installs                                                                                                 |
| [Phantom-dependency prevention](/docs/reference/package-json-lpm#strictdeps)        | Hoisted layout leaks unlisted deps | Isolated by default                                | In isolated mode                                                    | In isolated mode (default for workspaces and peer-conflict installs)                                                                                                                                          |
| [Lockfile](/docs/packages/lockfile)                                                 | `package-lock.json` v3             | `pnpm-lock.yaml` v9                                | `bun.lock` (JSONC)                                                  | `lpm.lock` (TOML, authoritative) plus `lpm.lockb` binary companion when the graph fits the binary format                                                                                                      |
| [Patched dependencies](/docs/packages/patch)                                        | —                                  | `pnpm patch` workflow                              | `bun patch` workflow                                                | Native `patchedDependencies`; reads pnpm's shape for migration                                                                                                                                                |
| [Dependency overrides](/docs/reference/package-json-lpm#overrides--resolutions)     | Yes (`overrides` field, npm 8+)    | Yes                                                | Yes                                                                 | Honors top-level npm `overrides`, Yarn `resolutions`, and `lpm.overrides`; `lpm migrate` translates `pnpm.overrides`                                                                                          |
| [Native dependency build-artifact cache](/docs/packages/rebuild#native-build-cache) | —                                  | Side-effects cache, enabled by default             | —                                                                   | Automatic for eligible strict-sandbox builds on macOS and Linux; content-addressed artifacts are reused only when package graph, platform, Node runtime/ABI, environment, sandbox, and toolchain inputs match |

## Developer orchestration and local infrastructure [#developer-orchestration-and-local-infrastructure]

This is the most lopsided table — three of the four columns are blank for several rows.

| Axis                                                                                           | npm                    | pnpm                    | bun                                                      | lpm                                                                                                                                                                                                         |
| ---------------------------------------------------------------------------------------------- | ---------------------- | ----------------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Secrets vault (E2E-encrypted, secure-store preferred, cloud sync)](/docs/infra/secrets-vault) | —                      | —                       | Auto-loads `.env`, no vault                              | Per-project and per-environment; prefers the OS secure store with encrypted-file fallback; org sharing, OIDC CI escrow, and client-direct Vercel, Coolify, Fly.io, Railway, and GitHub Actions integrations |
| [Zero-config dev server orchestrator](/docs/guides/zero-config-dev-server)                     | —                      | —                       | —                                                        | Auto-installs stale deps, loads env, starts services, opens the browser when ready, and starts LPM CLI's browser webhook inspector when tunneling                                                           |
| [Remote task cache](/docs/dev/task-runner#remote-cache)                                        | Use Turborepo / Nx     | Use Turborepo / Nx      | Use Turborepo / Nx                                       | Local task cache + hosted remote cache; content hashes always, optional HMAC signing via `remoteCache.signature`, read-only mode, quota / usage status, and env-policy upload guards                        |
| [Local HTTPS with dev-only certificate authority](/docs/infra/local-https)                     | Use `mkcert`           | Use `mkcert`            | Use `mkcert`                                             | Built-in CA: status / trust / uninstall / generate. Picked up automatically by the dev server.                                                                                                              |
| [Local tunneling (public URL to localhost)](/docs/infra/tunneling)                             | Use `ngrok`            | Use `ngrok`             | Use `ngrok`                                              | Stable claimable domains, webhook capture, replay, and audit log                                                                                                                                            |
| [Managed runtime availability](/docs/dev/node-version-pinning)                                 | —                      | Node version pinning    | Bun is its own runtime                                   | Auto-installed Node and Bun via `lpm.json > runtime`; Node also falls back through `engines.node`, `.nvmrc`, `.node-version`                                                                                |
| [Managed linter / formatter](/docs/dev/builtin-tools)                                          | —                      | —                       | Formatter exists in the runtime, not the install surface | oxlint + biome as lazy-downloaded plugins, pinned via `lpm.json > tools`                                                                                                                                    |
| [One-off package execution (npx-equivalent)](/docs/dev/dlx)                                    | `npx`, permanent cache | `pnpm dlx`, 1-day cache | `bunx`                                                   | `lpm dlx` / `lpx`, 1-day cache                                                                                                                                                                              |
| [Built-in bundler](/docs/dev/bundle)                                                           | —                      | —                       | Yes                                                      | No native bundler; `lpm bundle` uses managed Rolldown, while `lpm pack` wraps project-local tsdown                                                                                                          |
| Built-in test runner                                                                           | —                      | —                       | Yes                                                      | No native test engine; `lpm test` orchestrates Vitest / Jest / Mocha                                                                                                                                        |

## Code and package operations [#code-and-package-operations]

| Axis                                                                                                                        | npm                    | pnpm                            | bun                               | lpm                                                                                                                                                               |
| --------------------------------------------------------------------------------------------------------------------------- | ---------------------- | ------------------------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Source-code delivery (copy package files into the project, shadcn-style)](/docs/packages/add)                              | —                      | —                               | —                                 | `lpm add` — works for any tarball-shipped package on any reachable registry (lpm.dev, npm, private via `.npmrc`)                                                  |
| [Dependency selector queries (CSS-like syntax over behavioral tags)](/docs/packages/query)                                  | —                      | —                               | —                                 | `lpm query` — `:eval`, `:scripts:not(:built)`, `:root > :network`, `#express`, `--assert-none` CI gate                                                            |
| [Dependency-graph visualization](/docs/packages/graph)                                                                      | `npm ls` (text)        | `pnpm list` (text)              | `bun pm ls` (text)                | `lpm graph` / `lpm ls` — HTML / JSON / dot output, depth filter, `lpm why <pkg>` reverse-lookup                                                                   |
| [Interactive upgrade picker](/docs/packages/upgrade)                                                                        | —                      | `pnpm update -i`                | `bun update --interactive`        | `lpm upgrade [pkg...]` (interactive by default on TTY) — targeted upgrades, peer-impact analysis                                                                  |
| [License inventory and policy gate](/docs/packages/licenses)                                                                | third-party tooling    | third-party tooling             | third-party tooling               | `lpm licenses` — local inventory, `--fail-on copyleft,missing`, exact `--deny <LICENSE>` gates                                                                    |
| Programmable resolution hooks (intercept `readPackage` / `afterAllResolved` at resolve time)                                | —                      | `.pnpmfile.cjs`                 | —                                 | —                                                                                                                                                                 |
| [Install-time policy extensions](/docs/infra/policy)                                                                        | —                      | —                               | —                                 | Local `package.candidate` extensions evaluate resolved packages before fetch/link and return `allow`, `warn`, or `block`; they do not mutate resolution           |
| [Workspaces (monorepo)](/docs/packages/workspaces)                                                                          | `--workspace` selector | Rich `--filter` pattern syntax  | `--workspace`, `--all-workspaces` | pnpm-style filter grammar                                                                                                                                         |
| [Catalog version pins for monorepos (one declaration, every member references it)](/docs/packages/workspaces#catalogs)      | —                      | `pnpm-workspace.yaml > catalog` | Catalogs in lockfile              | `package.json > catalogs`, plus pnpm-style `pnpm-workspace.yaml` catalogs and cleanup                                                                             |
| [Workspace-package deploy (extract one member + transitive deps to a deployable dir)](/docs/packages/workspaces#lpm-deploy) | —                      | `pnpm deploy`                   | —                                 | `lpm deploy`                                                                                                                                                      |
| [Migration from other package managers](/docs/migrating)                                                                    | —                      | —                               | Reads npm + yarn lockfiles        | One-command lockfile migration from npm / pnpm / Yarn / Bun; pnpm migration also translates overrides, patches, and peer rules                                    |
| [Swift Package Manager (SE-0292)](/docs/packages/swift-package-registry)                                                    | —                      | —                               | —                                 | SE-0292-compatible after LPM CLI configures the scope; certificate/trust setup occurs on the first Swift install; CMS signing is available on a best-effort basis |

## Publishing and registry [#publishing-and-registry]

| Axis                                                                                   | npm                                     | pnpm                           | bun                                 | lpm                                                                                                                                                                                                                         |
| -------------------------------------------------------------------------------------- | --------------------------------------- | ------------------------------ | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [First-party hosted registry](/docs/registries)                                        | npmjs.org (public and private packages) | —                              | —                                   | lpm.dev: publish-time security analysis, with optional AI analysis and API-doc extraction; private publishers can opt out of AI processing. Packages are private by default, with pool and marketplace as explicit opt-ins. |
| [Sigstore provenance signing on publish](/docs/packages/publish#provenance)            | `--provenance` flag                     | Auto in CI when OIDC available | —                                   | `--provenance` flag + auto-OIDC token exchange                                                                                                                                                                              |
| [OIDC trusted-publisher token exchange](/docs/packages/publish#npm-trusted-publishing) | GitHub Actions                          | GitHub Actions + GitLab CI     | —                                   | GitHub Actions + GitLab CI                                                                                                                                                                                                  |
| [2FA on publish](/docs/packages/publish#authentication-and-otp)                        | OTP                                     | OTP                            | `--otp` flag                        | OTP                                                                                                                                                                                                                         |
| [`.npmrc` scope-to-registry routing](/docs/registries#pointing-at-a-private-registry)  | Yes                                     | Yes                            | Yes                                 | Yes — mappings are honored for npm-compatible private registries and JSR mirrors; per-origin authentication is supported                                                                                                    |
| [Auth-token storage](/docs/infra/authentication#token-storage)                         | `.npmrc` plain text                     | `.npmrc` plain text            | `.npmrc` / `bunfig.toml` plain text | OS keychain preferred; AES-256-GCM encrypted-file fallback; `.npmrc` honored for compatibility                                                                                                                              |
| [Default registry routing](/docs/registries#default-routing)                           | npmjs.org                               | npmjs.org                      | npmjs.org                           | npm packages go directly to npmjs.org; native `jsr:` dependencies go to npm.jsr.io; only `@lpm.dev/*` always routes through lpm.dev                                                                                         |

## Platform [#platform]

| Axis                                   | npm                  | pnpm                            | bun                      | lpm                                                                                                                                              |
| -------------------------------------- | -------------------- | ------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| macOS (Intel + Apple Silicon)          | Yes                  | Yes                             | Yes                      | Yes                                                                                                                                              |
| Linux (glibc)                          | Yes                  | Yes                             | Yes                      | Yes                                                                                                                                              |
| Linux (musl / Alpine)                  | Yes                  | Yes                             | Yes                      | Upcoming official x64 binary through npm, the standalone installer, and GitHub Releases (not included in v0.67.0); ARM64 requires a source build |
| Windows x64                            | Yes                  | Yes                             | Yes                      | Yes                                                                                                                                              |
| FreeBSD                                | Yes                  | Yes                             | —                        | —                                                                                                                                                |
| [Self-update](/docs/infra/self-update) | `npm install -g npm` | `pnpm self-update`              | `bun upgrade`            | `lpm self-update` — install-method-aware (npm / Homebrew / Cargo / standalone GitHub Releases); 24-hour banner check                             |
| Implementation language                | JavaScript (Node.js) | TypeScript (Rust port underway) | Zig (Rust port underway) | Rust                                                                                                                                             |

## See also [#see-also]

* [Migrating to LPM CLI](/docs/migrating) — one-command path from any of the above
* [Secrets vault](/docs/infra/secrets-vault) — the storage and encryption design
* [Zero-config dev server](/docs/guides/zero-config-dev-server) — what `lpm dev` auto-detects
* [Tunneling](/docs/infra/tunneling) — public URLs to localhost
* [Local HTTPS](/docs/infra/local-https) — the dev certificate authority
* [Package audit](/docs/packages/security-audit) — the audit pipeline
