pnpm Documentation

website·Indexed 43 days ago

https://pnpm.io/

Documentation for pnpm, a performant alternative to npm. Covers package management, workspace task orchestration, native release management (v11.13.0+), and configuration settings for node_modules, registries, and lockfiles. Includes details on the pnpm CLI (v12.x), SBOM generation, and the Rust-based pnpr registry server.

Tokens
158.5K
Snippets
980
Records
1.4K
Agent score
72%

What's inside pnpm

  1. Overview of pnpr registry server

    pnpr is a pnpm-compatible registry server written in Rust that implements the npm registry protocol. It allows any npm-compatible client (pnpm, npm, yarn) to interact with it. It can host private packages and proxy upstream registries (like registry.npmjs.org) with custom authentication and access controls.

    Beyond npm, pnpr supports Cargo (Rust), Python, and the OCI distribution API for container images. It prevents dependency-confusion attacks by using a router that resolves each package name to exactly one declared registry origin, eliminating cross-origin fall-through.

  2. Overview of pnpm shared side-effects cache

    The shared side-effects cache extends pnpm's local sideEffectsCache across multiple machines. Instead of every machine executing a dependency's build script, a trusted builder publishes the build output to a pnpr server. Other consumers can then restore this signed output, skipping the local build process. This feature is a proof of concept (added in pnpr v0.1.0-alpha.8, pnpm v11.25.0 and v12.0.0) and supports Linux/glibc, macOS, and Windows on x64 and arm64. If the remote cache is unreachable or verification fails, pnpm falls back to a standard local build.
  3. Overview of pnpr registry server

    pnpr is a pnpm-compatible registry server written in Rust that implements the npm registry protocol. It allows any npm-compatible client (pnpm, npm, yarn) to interact with it. It functions as a private package host and a proxy for upstream registries (like registry.npmjs.org) with its own authentication and access controls.

    Key capabilities include:

    • Multi-protocol support: Beyond npm, it supports Cargo (Rust), Python, and the OCI distribution API for container images.
    • Cross-ecosystem publishing: A single workspace can publish a package, a crate, a Python distribution, and a container image in one transaction.
    • Security: It prevents dependency-confusion attacks by resolving each package name to exactly one declared registry origin, eliminating cross-origin fall-through.
    • Authentication: Supports sign-in via OpenID Connect (OIDC).

    Note: pnpr is currently experimental and in active development; APIs and configuration may change between releases.

  4. Overview of pnpm Store and Lockfile settings

    pnpm provides several settings to manage the content-addressable store and the lockfile behavior. Key settings include storeDir for specifying the store location, verifyStoreIntegrity for checking store health, and frozenStore for CI environments. Lockfile behavior can be controlled via lockfile (format selection) and preferFrozenLockfile to prevent lockfile updates during installation.
  5. Overview of pnpm staged publishing

    Introduced in v11.3.0, pnpm stage allows developers to use npm's staged publishing workflow. Staged versions are uploaded to the registry but are not resolvable by pnpm install until they are explicitly approved. This is useful for verifying release artifacts, smoke-testing CI, or coordinating multi-package releases while deferring 2FA (one-time password) requirements to the final approval step.
    pnpm stage <subcommand> [options]
  6. Overview of pnpm hooks and .pnpmfile.cjs

    pnpm allows you to hook into the installation process using special functions declared in a file named .pnpmfile.cjs. This file should be located in the same directory as the lockfile (e.g., the root of a monorepo in a workspace setup).
  7. Use pnpm native release management

    Since v11.13.0, pnpm can manage workspace releases natively without requiring the Changesets CLI. It is compatible with the .changeset/*.md file format. Additionally, since v11.16.0, pnpm update --changeset can automatically write a changeset for dependency bumps.
  8. Understand how pnpm manages disk space with hard links

    pnpm uses hard links to connect the global store to a project's node_modules. A hard link points to the same physical location on the disk as the original file. Consequently, if a package occupies 1MB, it will appear to occupy 1MB in the global store and 1MB in the project's node_modules, but the total disk space used is only 1MB because both entries address the same data.
  9. Manage Node.js runtimes with pnpm

    pnpm allows developers to install and pin specific Node.js versions per project directly through the package manager, removing the need for external version managers like nvm or shell hooks.
  10. Understand PATH resolution for pnpm scripts

    When running scripts, pnpm automatically adds node_modules/.bin to the PATH. In workspaces, <workspace root>/node_modules/.bin is also added. This allows scripts to call locally installed binaries (like eslint) without requiring them to be installed globally.
    "scripts": {
        "lint": "eslint src --fix"
    }
  11. Manage per-package release lanes with pnpm lane

    The pnpm lane command manages parallel release tracks. When a package is assigned to a lane, pnpm version -r releases it as a prerelease (X.Y.Z-<lane>.N) while other packages in the workspace continue to release stable versions. Lane membership is stored under the versioning.lanes key in pnpm-workspace.yaml. Lane names must be alphanumeric or hyphens and cannot be purely numeric.
  12. Understand pnpm's symlinked node_modules structure

    pnpm uses a combination of hard links and symbolic links to manage dependencies, avoiding the issues associated with flattened node_modules (like phantom dependencies).

    1. Hard Linking: Every file of every package is hard-linked from the content-addressable store into a hidden folder: node_modules/.pnpm. Packages are stored in folders named by their version (e.g., .pnpm/foo@1.0.0/node_modules/foo).
    2. Symlinking Dependencies: Dependencies are symlinked into the node_modules folder of the package that depends on them. For example, if foo depends on bar, a symlink is created at .pnpm/foo@1.0.0/node_modules/bar pointing to the real location of bar.
    3. Root Access: Only direct dependencies listed in the project's package.json are symlinked into the root node_modules folder, making them accessible to the application code.

    This structure ensures that packages can only access dependencies they have explicitly declared, while remaining compatible with Node.js's module resolution algorithm.

    node_modules
    ├── foo -> ./.pnpm/foo@1.0.0/node_modules/foo
    └── .pnpm
        ├── bar@1.0.0
        │   └── node_modules
        │       └── bar -> <store>
        └── foo@1.0.0
            └── node_modules
                ├── foo -> <store>
                └── bar -> ../../bar@1.0.0/node_modules/bar