Compared to npm, pnpm, bun
Side-by-side defaults across the four JavaScript package managers — security, resolution, developer orchestration, publishing, and platform.
A factual comparison of default behavior across npm 11, pnpm 11, bun 1.4, and lpm.
| npm | pnpm | bun | lpm |
|---|
| Cold install, equal footing ¹ | 6,735ms | 1,124ms | 823ms | 957ms |
| Cold install, reset-each-iter ² | 7,146ms | 1,927ms | 1,207ms | 945ms |
| Warm install ³ | 648ms | 665ms | 263ms | 23ms |
| Up-to-date install ³ | 348ms | 152ms | 8ms | 6ms |
| Script overhead ⁴ | 67ms | 107ms | 6ms | 9ms |
lpm lint vs npx oxlint ⁴ | 250ms | — | — | 78ms (3.2×) |
lpm fmt vs npx biome ⁴ | 264ms | — | — | 13ms (20×) |
| Axis | npm | pnpm | bun | lpm |
|---|
| Install-time process sandbox | — | — | — | Default: macOS Seatbelt deny-default, Linux landlock V1 filesystem deny-default, Windows AppContainer (Low IL MIC + Job Object fallback if helper absent). Strict: adds outbound network denial; Linux upgrades to landlock V4 + seccomp socket-deny (kernel ≥6.7; refused otherwise unless allow-degraded = true). |
Lifecycle scripts (preinstall / install / postinstall) | 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 | Blocked by default; opt-in triage policy adds a four-layer gate (greens auto-approve; ambers/reds still blocked) |
| Sigstore verification on install | Manual via audit signatures | Mints attestations on publish; pnpm audit signatures matches npm; resolve-time trust-evidence rank check refuses installs when current evidence (trustedPublisher / provenance / none) is weaker than any earlier version's | — | DSSE + Rekor body + Rekor SET + SCT + X.509 chain verified end-to-end on install, including attestations served by npmjs |
| Minimum release age (cooldown) | min-release-age flag, off by default | 1-day cooldown by default | Off by default | 1-day cooldown by default |
engines.node enforcement | Warn only | Warn only | — | Hard-fails install / rebuild / add before any IO |
| Built-in vulnerability audit | npm security database | Registry-side data | Proxies to npm audit endpoint | OSV + behavioral analysis + verdict cache |
| Approval-gated weakening of security posture | — | — | — | 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 | — | Resolve-time trust-rank downgrade refusal (trustedPublisher → provenance → none) | — | Trust binding per package + drift detection when a publisher identity changes |
| 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) |
| Axis | npm | pnpm | bun | lpm |
|---|
| Resolver | Arborist backtracking | Highest-version + workspace-rooted peer resolution | Tree resolution + backtracking | Greedy-fusion (PubGrub legacy arm available) |
| Package store | Content-addressable cache | Content-addressable, versioned virtual store | Content-addressable, hardlinked | Content-addressable, clonefile on macOS (mutation-safe COW) |
node_modules layout | Hoisted | Isolated (symlinked virtual store) | Auto: hoisted for single-package, isolated when workspaces detected | Auto: hoisted for single-package, isolated for workspaces or default peer-conflict installs |
| Phantom-dependency prevention | Hoisted layout leaks unlisted deps | Isolated by default | In isolated mode | In isolated mode (default for workspaces and peer-conflict installs) |
| Lockfile | package-lock.json v3 | pnpm-lock.yaml v9 | bun.lock (JSONC) | Dual write: lpm.lock (TOML, git-diffable) + lpm.lockb (binary mmap, zero-parse on warm install) |
| Patched dependencies | — | pnpm patch workflow | bun patch workflow | Native patchedDependencies; reads pnpm's shape for migration |
| Dependency overrides | Yes (overrides field, npm 8+) | Yes | Yes | Honors npm and pnpm shapes |
Side-effects cache for native builds (cache node-gyp output so sharp / node-sass skip rebuild on re-install) | — | Default on | — | — |
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, OS-keychain-backed, cloud sync) | — | — | Auto-loads .env, no vault | Per-project, per-environment, org-shareable, OIDC CI escrow, platform pushes to Vercel / AWS SSM / Fly / Railway / Coolify / GitHub Actions |
| Zero-config dev server orchestrator | — | — | — | Auto-installs stale deps, loads env, starts services, wires the Node inspector, opens the browser when ready |
| Remote task cache | Use Turborepo / Nx | Use Turborepo / Nx | Use Turborepo / Nx | Local task cache + hosted remote cache; signed artifacts, read-only mode, quota / usage status, and env-policy upload guards |
| Local HTTPS with dev-only certificate authority | 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) | Use ngrok | Use ngrok | Use ngrok | Stable claimable domains, webhook capture, replay, and audit log |
| Managed runtime availability | — | 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 |
| Built-in linter / formatter as install-time 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) | npx, permanent cache | pnpm dlx, 1-day cache | bunx | lpm dlx / lpx, 1-day cache |
| Built-in bundler | — | — | Yes | No native bundler; lpm bundle (rolldown) and lpm pack (tsdown) ship as lazy-downloaded plugin engines |
| Built-in test runner | — | — | Yes | — |
| Axis | npm | pnpm | bun | lpm |
|---|
| Source-code delivery (copy package files into the project, shadcn-style) | — | — | — | 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) | — | — | — | lpm query — :eval, :scripts:not(:built), :root > :network, #express, --assert-none CI gate |
| Dependency-graph visualization | npm ls (text) | pnpm list (text) | bun pm ls (text) | lpm graph — HTML / JSON / dot output, depth filter, --why <pkg> reverse-lookup |
| Interactive upgrade picker | — | pnpm update -i | bun update --interactive | lpm upgrade (interactive by default on TTY) — dual-row WithinMajor + AbsoluteLatest, peer-impact analysis |
Programmable resolution hooks (intercept readPackage / afterAllResolved at resolve time) | — | .pnpmfile.cjs | — | — |
| Workspaces (monorepo) | --workspace selector | Rich --filter pattern syntax | --workspace, --all-workspaces | Rich filter engine matching pnpm's pattern surface |
| Catalog version pins for monorepos (one declaration, every member references it) | — | 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) | — | pnpm deploy | — | lpm deploy |
| Migration from other package managers | — | — | Reads npm + yarn lockfiles | One command from npm / pnpm / yarn / bun, preserving overrides, patches, and peer rules |
| Swift Package Manager (SE-0292) | — | — | — | SPM resolves lpm packages natively; CMS-signed Swift releases; auto-installs the signing certificate on first use |
| Axis | npm | pnpm | bun | lpm |
|---|
| First-party hosted registry | npmjs.org (public and private packages) | — | — | lpm.dev (every package security-analyzed and API documentation auto-generated by AI; private packages + monetization via pool or marketplace options) |
| Sigstore provenance signing on publish | --provenance flag | Auto in CI when OIDC available | — | --provenance flag + auto-OIDC token exchange |
| OIDC trusted-publisher token exchange | GitHub Actions | GitHub Actions + GitLab CI | — | GitHub Actions + GitLab CI |
| 2FA on publish | OTP | OTP | --otp flag | OTP |
.npmrc scope-to-registry routing | Yes | Yes | Yes | Honored across npm, lpm.dev, and private registries; per-origin auth tokens |
| Auth-token storage | .npmrc plain text | .npmrc plain text | .npmrc / bunfig.toml plain text | OS keychain (macOS Keychain / Linux Secret Service / Windows Credential Manager); .npmrc honored for tooling compat |
| Default registry routing | npmjs.org | npmjs.org | npmjs.org | Direct to npmjs.org for npm packages; lpm.dev only for @lpm.dev/* |
| 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 | Yes — detected at runtime, folded into store keys |
| Windows | Yes | Yes | Yes | Yes |
| FreeBSD | Yes | Yes | — | — |
| 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 |