mrkeyoor.com_
Tue 29 Sept 18:26 UTC
Dev Toolsevaluationupdated 26 Aug 2026

pnpm review

pnpm is a package manager for JavaScript and Node.js projects that stores package files once and links them into each project. It reduces duplicated disk use, enforces declared dependencies more strictly than a flat `node_modules`, and includes serious workspace and supply-chain controls.

+65stars / 7d
Verdict

Our pnpm repository run installed 1 detected package in 96 seconds, but exposed no build or test target, so it tells us little about the 787,801-line monorepo's correctness. Even with that evidence gap, pnpm is our first choice for a new Node workspace because strict dependency visibility and shared storage solve daily problems. Pin v11.24.0, test CI and deployment paths, and use broad hoisting only for a documented compatibility failure.

We ran it

Lab card: what happened when we ran pnpmScreenshot of pnpm (pnpm.io)
Install✓ · 96s1 packages · 9 MB
Buildn/ano build script
Testsn/ano test script
Repo5851 files~787,801 lines of source · 38.9 MB · 24 CI workflows

Answers from our run

Does pnpm build from source?

Dependencies installed in 96 seconds (1 packages), and the project has no separate build step. We cloned commit dfa6a43 into a clean Debian container with 3 CPUs and no project-specific setup.

Does pnpm have tests you can run?

Not through a standard command: the project exposes no test script or target that our harness could run.

Who should not use pnpm?

Projects tied to Node.js 18 or 20 that want to install pnpm 11 as a normal Node package: the compatibility table requires Node.js 22 or newer for that path.

What are the alternatives to pnpm?

npm, Yarn, Bun. Our pnpm repository run installed 1 detected package in 96 seconds, but exposed no build or test target, so it tells us little about the 787,801-line monorepo's correctness.

Setup4/5Easy install, with real migration work for existing repositories
Docs5/5Exceptional coverage of commands, layouts, security, and migration
Community5/5Large adoption, frequent releases, and same-day issue activity
Maturity5/5Production use since 2016, with a stable line during the rewrite

Discussed on

  1. hnhttps://github.com/pnpm/pnpm: 404 Not Found4 points
  2. hnNPM retires audit endpoint; breaks pnpm audit4 points
  3. hnpnpm 94 points
  4. hnPNPM vs Yarn: monorepo node_modules4 points
  5. hnpnpm 73 points

Who it’s for

JavaScript teams with many local projects that want to stop storing a full duplicate of every package in each one.
Monorepo maintainers who need workspace linking, filtering, catalogs, patches, and a deterministic lockfile.
Security-conscious teams that want dependency build scripts denied until approved and newly published versions delayed by default.
Organizations willing to pin the package-manager version and test the install layout across local development, CI, containers, and deployment.

Who it’s NOT for

Projects tied to Node.js 18 or 20 that want to install pnpm 11 as a normal Node package: the compatibility table requires Node.js 22 or newer for that path.
React Native or serverless deployments that cannot handle symlinks without configuration: pnpm's docs name these as reasons to use a hoisted layout instead.
Teams relying on undeclared, hoisted dependencies and unwilling to repair manifests: pnpm intentionally restricts application code to declared dependencies by default.
Developers who expect every dependency build script to run without review: current defaults reject unapproved scripts until allowBuilds decisions are recorded.
Organizations requiring every directory in the repository to use the MIT license: the README exempts pnpr/, which uses the PolyForm Shield License.
Early adopters who cannot absorb rewrite regressions: the README labels the Rust pacquet CLI port experimental.

Setup reality

Our Node 22 sandbox installed the one package exposed by the detected target in 96 seconds, using 9 MB on disk. The repository provided no build script or target and no test script or target, so both steps were skipped.

Installing the pnpm CLI is easy through a standalone script, npx get-pnpm, or system package managers. Repository adoption is the work: pin a version, commit pnpm-lock.yaml, replace CI caches, review build-script approvals, and repair undeclared dependencies.

Commit dfa6a43 was a 38.9 MB monorepo with 5,851 files and about 787,801 source lines. Tooling that assumes flat folders or cannot follow symlinks may require targeted hoisting.

What happened when we ran it

Our Node 22 sandbox installed the 1 package exposed by the detected target in 96 seconds, using 9 MB on disk. commit dfa6a43 was a 38.9 MB checkout with 5,851 files and about 787,801 source lines. That mismatch is important: the install step did not exercise the dependency graph of every workspace in this large monorepo.

The repository exposed no build script or target and no test script or target to our generic runner, so both stages were skipped. The tree contains 24 CI workflow files but no top-level tests directory. We did not turn a missing generic target into a passing result; our run only confirms that the detected install completed.

Shared storage and strict imports are the practical case

pnpm stores package files in a content-addressable store and links them into projects, allowing multiple repositories to reuse identical content. Its isolated layout also stops application code from casually importing transitive packages absent from its manifest.

The project claims installs can be up to 2 times faster than npm and Yarn Classic. That is its figure, not ours, and cache state or CI architecture can change it. Shared storage and strict dependency declarations are the dependable reasons to choose pnpm.

Strict dependencies catch real mistakes

pnpm's default isolated layout places package contents under node_modules/.pnpm and uses links to recreate the dependency graph. Application code sees packages declared in its own manifest, instead of accidentally importing a transitive package that happened to be hoisted to the root. A lockfile records the selected graph in pnpm-lock.yaml.

This catches a class of bugs that npm's traditionally flat layout can hide. If an application imports a library without declaring it, pnpm is more likely to fail locally rather than let the mistake reach a consumer with a different dependency tree. Packages can still access an internal hoisted area for ecosystem compatibility, but undeclared modules are not generally exposed to application code.

The downside is that parts of the JavaScript ecosystem still assume flat folders or follow symlinks poorly. pnpm documents a hoisted linker for React Native, serverless systems that reject symlinks, bundled dependencies, and certain Node flags. Targeted hoistPattern and publicHoistPattern settings can accommodate flawed tools. The tempting shamefullyHoist option makes everything visible at the root, but the docs strongly discourage it. Use it only after identifying the package that breaks and trying a narrow pattern.

Workspaces are a first-class reason to switch

A pnpm-workspace.yaml file turns a repository into a workspace. The workspace: protocol can require a dependency to resolve to a local package, so an absent or mismatched local version fails instead of silently pulling a registry copy. During packing or publishing, pnpm converts that protocol into a regular version range that consumers can install with any package manager.

That is a small feature with large practical value. Local development tests the code that will actually be released, and accidental registry fallbacks become visible. Recursive commands and filters let teams run scripts over selected packages and their dependents. Catalogs centralize versions shared across packages, while patches and overrides handle upstream defects without forking an entire dependency.

Migration is still work. Teams must replace the old lockfile, change CI installs to pnpm, define cache paths, pin the package-manager version, and test publishing. Cyclic workspace dependencies can prevent scripts from running in topological order. The current tool has native release-management features, but organizations already using Changesets or Rush should compare workflows before replacing a proven release process.

Security defaults that users will notice

Since v10, pnpm has stopped treating a dependency's install script as automatically trusted. Current v11 settings put allowed and denied package matchers in pnpm-workspace.yaml; unreviewed build scripts are disallowed, and strictDepBuilds makes the install fail by default. This blocks a common route for a compromised package to execute code immediately. It also means packages such as native compilers may not work until a maintainer approves their builds. That friction is deliberate and belongs in onboarding documentation.

pnpm 11 also defaults minimumReleaseAge to 1,440 minutes. A package version published less than a day ago is normally held back, giving registries and security services time to identify malware. Teams can opt out or increase the delay. Other controls can block transitive Git or direct-URL dependencies, enforce a no-downgrade trust policy, qualify packages by named registry in the lockfile, and refuse a tarball whose current checksum differs from the committed integrity.

These are excellent defaults for an organization, but not invisible ones. A just-published bug fix may appear unavailable, and a dependency that previously built itself may stop at review. Document how maintainers grant exceptions, commit the decisions, and handle emergency upgrades. Do not solve the inconvenience with dangerouslyAllowAllBuilds, which restores execution rights for every present and future transitive dependency.

Version pinning matters more than the installer

Stable pnpm 11 can be installed through common system package managers, a standalone executable, or npx get-pnpm. If it is not installed through the standalone build or @pnpm/exe, it requires Node.js 22 or newer. Intel Mac users cannot use the v11 standalone script, and Windows users are steered toward npm because Defender may block the executable. CI should use a frozen lockfile, which pnpm enables by default when it detects a CI environment.

The repository labels its Rust pacquet CLI port experimental, while v11.24.0 is the current numbered release. That release arrived on August 24, 2026, and the repository was pushed on August 26. GitHub listed 2,500 open issues and pull requests, a large combined queue; same-day patches and bug reports show intense activity rather than neglect.

For most teams, the sensible choice is pinned v11.24.0 with an exact version pinned in the repository. Trial it against representative development, CI, container, and deploy paths. Fix manifest mistakes instead of masking them globally. If those tests pass, pnpm offers a rare combination: lower storage waste, better monorepo ergonomics, stricter dependency boundaries, and security policy that lives with the code.

Alternatives

ProjectWhat it isPick it when
npmThe package manager bundled with Node.js, with the least extra setup and broad ecosystem assumptions.pick this instead when universal familiarity and the default Node toolchain matter more than pnpm's store and stricter layout.
YarnA mature package manager with workspaces, plugins, constraints, and Plug'n'Play support.pick this instead when Plug'n'Play, zero-installs, or Yarn's policy and plugin system is central to the repository.
Bun gh↗A JavaScript runtime and toolkit that includes a fast package manager, test runner, and bundler.pick this instead when you want one runtime-centered toolchain and are prepared to validate Bun compatibility beyond installation.

What people are saying

  1. [github-trending] pnpm/pnpm

Sources

  1. pnpm repository
  2. pnpm installation guide
  3. pnpm workspace documentation
  4. Symlinked node_modules structure
  5. Mitigating supply-chain attacks with pnpm
  6. pnpm build settings
  7. pnpm 11.24 release
  8. Alpine packageManager delegation regression

More dev tools reviews

Kaku · kordoc · hey · wechat-miniapp-radar · omarchy-workspace-layout · fermats-last-theorem · the whole board →