Nodejs Pnpm
> As a Node.js developer, you're certainly familiar with `npm` and `yarn` - powerful tools for managing project dependencies. But have you encountered issues like massive `node_modules` folders, slow installation speeds, or rapidly consumed disk space? This is where pnpm shines.
**pnpm** is a fast, disk space-efficient Node.js package manager that stores packages through content addressing. All dependency versions are centrally stored in a system-wide location, then linked to projects via hard links to avoid redundant installations.
pnpm's slogan is **Fast, disk space efficient package manager**, offering blazing-fast speeds and significant disk space savings through its unique linking mechanism.
---
## Installing pnpm
There are multiple ways to install pnpm, choose based on your preference and system environment.
### Method 1: Install via npm (Recommended for all users)
This is the most universal and simple method. Open your terminal (Windows users can use PowerShell or CMD) and run:
```bash
npm install -g pnpm
This command installs pnpm globally through npm.
**Verify installation success**: After installation, check the version with the following command. If the version number displays normally, the installation was successful.
```bash
pnpm --version
Output example: 8.15.0
### Method 2: Install via standalone script
For macOS or Linux users:
```bash
# macOS/Linux
curl -fsSL https://get.pnpm.io/install.sh | sh -
For Windows (PowerShell):
```powershell
# Windows (PowerShell)
iwr https://get.pnpm.io/install.ps1 -useb | iex
---
## Using pnpm
Now let's start using pnpm in practice. Its command design is very intuitive, and if you're familiar with npm, you can switch seamlessly.
### Initialize a new project
Similar to `npm init`, pnpm can initialize a project and create a `package.json` file.
```bash
# Interactively create package.json
pnpm init
# Quickly create package.json with default values
pnpm init -y
After running `pnpm init -y`, you'll get a basic `package.json` file:
## Example
```json
{
"name": "your-project-name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
### Install dependencies
The installation command is `pnpm add `, equivalent to `npm install `.
```bash
# Install all dependencies
pnpm install
# Add dependency package
pnpm add
# Add dev dependency
pnpm add -D
# Add global package
pnpm add -g
# Install specific version
pnpm add @
### Update dependencies
```bash
# Update all dependencies
pnpm update
# Update specific package
pnpm update
# Update to latest version (ignores version range in package.json)
pnpm update --latest
### Remove dependencies
```bash
pnpm remove
### Run scripts
```bash
# Run scripts defined in package.json
pnpm run
# Common shorthand commands
pnpm start
pnpm test
pnpm build
### npm to pnpm command comparison table
| npm command | pnpm command |
| --- | --- |
| `npm install` | `pnpm install` |
| `npm install ` | `pnpm add ` |
| `npm install --save-dev` | `pnpm add -D ` |
| `npm install --global` | `pnpm add -g ` |
| `npm update` | `pnpm update` |
| `npm uninstall ` | `pnpm remove ` |
| `npm run ` | `pnpm run ` |
| `npx ` | `pnpm dlx ` |
| `npm list` | `pnpm list` |
| `npm outdated` | `pnpm outdated` |
| `npm audit` | `pnpm audit` |
---
## Configuration Files
pnpm supports configuration through `.npmrc` files.
Create this file in your project root to customize pnpm behavior.
### Common configuration examples
```ini
# Set domestic mirror source (Taobao)
registry=https://registry.npmmirror.com
# Auto-install peer dependencies
auto-install-peers=true
# Strict mode
strict-peer-dependencies=true
# Shamefully hoist (dependency hoisting, compatible with certain tools)
shamefully-hoist=true
# Specify node_modules directory structure
node-linker=hoisted
# Set storage directory
store-dir=~/.pnpm-store
View current configuration:
```bash
pnpm config list
Set configuration:
```bash
pnpm config set
---
## Workspace
pnpm has built-in powerful monorepo support.
Define workspaces by creating a `pnpm-workspace.yaml` file in your project root.
Configuration example:
```yaml
packages:
- 'packages/*'
- 'apps/*'
- '!**/test/**'
Project structure example:
my-monorepo/
βββ pnpm-workspace.yaml
βββ package.json
βββ packages/
β βββ package-a/
β β βββ package.json
β βββ package-b/
β βββ package.json
βββ apps/
βββ web-app/
βββ package.json
### Workspace commands
```bash
# Install dependencies in all workspace packages
pnpm install
# Execute command in specific workspace
pnpm --filter
# Execute command in all workspaces
pnpm -r
# Recursively run script
pnpm -r run build
# Add dependency to workspace
pnpm --filter add
# Add internal workspace dependency
pnpm --filter package-a add package-b@workspace:*
### Workspace protocol
When referencing other packages in workspace, use the `workspace:` protocol:
```json
{
"dependencies": {
"package-a": "workspace:*",
"package-b": "workspace:^1.0.0"
}
}
---
## Advanced Features
### pnpm exec vs pnpm dlx
```bash
# Execute locally installed package
pnpm exec
# Execute remote package (similar to npx)
pnpm dlx create-react-app my-app
# Use specific version
pnpm dlx create-react-app@latest my-app
### View dependency tree
```bash
# View dependency tree
pnpm list
# Specify depth
pnpm list --depth 2
# Show only production dependencies
pnpm list --prod
# View global packages
pnpm list -g
### Check outdated dependencies
```bash
pnpm outdated
### Audit dependency security
```bash
pnpm audit
# Automatically fix security issues
pnpm audit --fix
### Clean cache
```bash
# Clean unused packages
pnpm store prune
# View storage location
pnpm store path
# View storage status
pnpm store status
### Import lockfile
When migrating from other package managers:
```bash
# Import from package-lock.json
pnpm import
# Import from yarn.lock
pnpm import
### Patch packages
When you need to temporarily modify a dependency:
```bash
# Create patch
pnpm patch @
# Commit patch after application
pnpm patch-commit
---
## What is pnpm? What are its core advantages?
Before diving deeper, we need to understand pnpm's core philosophy and the changes it brings.
**pnpm (Performant npm)** is a Node.js package manager that's backward compatible with npm, meaning most `npm` commands work directly in `pnpm`.
pnpm's design goals address the disk space and installation speed bottlenecks of traditional package managers (like npm, yarn).
### Problems with traditional package managers
Imagine you're working on 10 different frontend projects at your company, each depending on `lodash@4.17.21`. With npm or yarn, this `lodash` package gets downloaded and stored completely 10 times in 10 different `node_modules` folders on your computer. This creates massive disk space waste.
### pnpm's revolutionary solution: Content-addressable storage & hard links
pnpm uses a smart approach:
1. **Global storage**: When you install a package, pnpm stores its content in a **global, single-version repository** (usually located at `~/.pnpm-store`).
2. **Hard links**: In your project's `node_modules`, pnpm doesn't copy the full package files, but creates **hard links** pointing to the files in the global storage. Think of hard links as "advanced shortcuts" that share the same disk data as the original files.
3. **Symbolic link organization**: To maintain a flat `node_modules` structure (for `require` statements to work), pnpm creates a sophisticated system of **symbolic links** (soft links) to organize the dependency tree.
Through this mechanism, **no matter how many projects depend on the same package, it's physically stored only once on disk**. This brings immediate benefits:
* **Massive disk space savings**: Especially significant for developers with multiple projects
* **Blazing-fast installation speed**: Subsequent installations are much faster as pnpm only needs to create links when packages already exist in global storage
* **Enhanced security**: Package files in `node_modules` are read-only (due to hard links), preventing accidental modification of dependency content by project scripts and ensuring dependency determinism
!(#)
The above image clearly shows pnpm's core workflow: All projects share the same package files through hard links from global storage, then build dependency structures in their respective `node_modules` through symbolic links.
| Feature Comparison | npm (v7+) / yarn | **pnpm** |
| --- | --- | --- |
| **Disk Space Usage** | Each project's dependencies are stored independently, consuming significant space | All projects share **single copy** of dependencies, minimal space usage |
| **Installation Speed** | Slower, needs to download, extract, and build dependency tree | **Extremely fast**, especially subsequent installations which mainly create links |
| **`node_modules` Structure** | Flat or semi-flat, may cause dependency hoisting and phantom dependencies | **Strict** non-flat structure, accurately simulates dependency relationships, eliminates phantom dependencies |
| **Monorepo Support** | Supported through Workspaces but with performance bottlenecks | **Native, efficient** Workspaces support, performance is a strong suit |
| **Package Management Model** | Copies files to project during installation | Linking model (hard links + symbolic links) |
| **Security** | Dependencies can be modified by project scripts | Dependency files are read-only hard links, higher security |
**Official Resources**:
* (https://pnpm.io/)
* (https://pnpm.io/zh/)
* (https://github.com/pnpm/pnpm)
YouTip