Understanding pnpm: High‑Performance npm, Monorepo Support, and Practical Usage Guide
This article explains what pnpm is, how it saves disk space and speeds up installations using hard links and symlinks, introduces the monorepo development model and its relationship with package managers, and provides step‑by‑step instructions for installing pnpm, configuring workspaces, and managing dependencies in a monorepo setup.
What is pnpm? pnpm, short for "performant npm," is a high‑performance npm alternative that reduces disk usage and speeds up installations by using hard links and symbolic links.
Saving Disk Space and Improving Installation Efficiency pnpm stores a single copy of each package version in a global store and creates hard links or symlinks in each project's node_modules . Hard links share the same disk address, while symlinks act like shortcuts, preventing duplicate copies and accelerating installs.
When using npm, 100 projects with the same dependency would store 100 copies of that package. pnpm keeps a single copy in a central location; only files that differ between versions are added, dramatically reducing disk usage and installation time.
Non‑Flat node_modules Structure pnpm creates a nested node_modules layout that mirrors the dependency tree, avoiding the flat structure of npm.
Monorepo Overview and Relation to Package Managers
A monorepo (monolithic repository) stores all related projects and components in a single codebase. Package managers like npm, Yarn, and pnpm support workspaces, allowing multiple packages to be managed together, sharing dependencies and simplifying builds.
These tools integrate with monorepos by providing workspace support, enabling shared dependency installation and management across sub‑projects.
Monorepo Development Model
Returns to the advantages of a single repository while retaining some benefits of multiple repos.
Modern tools (pnpm, Yarn, Lerna, Turborepo) make monorepo feasible.
Advantages: code reuse, independent module management, clearer responsibilities, reduced coupling, easier version control.
Disadvantages: repository can become large and complex, longer build times, higher git clone/pull costs, and more difficult fine‑grained permission management.
Addressing Fine‑Grained Permission Issues in Monorepos
Solutions include using CODEOWNERS files, CI/CD gatekeeping, strict branch strategies (e.g., Git Flow), Git hooks, Git submodules, and third‑party platforms like GitLab or Bitbucket that offer detailed access controls.
Why Component Libraries Choose Monorepo
Component libraries often split into packages such as components , shared , theme , cli , docs , and playground . Clear module separation improves reusability, flexibility, and reduces bundle size.
pnpm Installation and Basic Commands
Install pnpm globally:
npm i pnpm -gCheck version:
pnpm -vUsing pnpm in a Monorepo Architecture
Example structure: a main app, plus React and Vue apps under a web folder, all managed by pnpm.
1. Initialize the root workspace:
pnpm init2. Create pnpm-workspace.yaml :
packages:
# main project
- 'main-project'
# all sub‑projects under web
- 'web/**'3. Install all dependencies in one command:
pnpm i4. Expose shared utilities:
Create a common folder with index.ts .
Run pnpm init inside common .
Add common to pnpm-workspace.yaml .
Export functions, e.g., export const hello = () => { console.log('hello') } .
Link the package to main-project with pnpm -F main-project add common (‑F is short for --filter ).
5. Import the shared method in the page and start the project:
pnpm -F main-project devCommon Pitfalls
When adding a package to all sub‑projects, the correct filter syntax is:
pnpm -F "./packages/*" add commonpnpm Common Commands
# Install a package and its dependencies (workspace‑aware)
pnpm add
# Install all project dependencies
pnpm install
# Update packages to latest versions
pnpm update
# Remove a dependency
pnpm remove
# Run a script
pnpm run
# Initialize a package.json
pnpm init
# List installed packages as a tree
pnpm listIn workspace mode, --filter allows fine‑grained operations on specific packages, e.g., installing external dependencies for a package a :
// Install lodash as a production dependency for package a
pnpm --filter a i -S lodash
// Install lodash as a dev dependency for package a
pnpm --filter a i -D lodashSpecifying internal dependencies uses the workspace: protocol, for example:
{
"name": "a",
"dependencies": {
"b": "workspace:^"
}
}During publishing, workspace:^ is replaced with the actual version of package b (e.g., ^1.2.3 ).
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.