← Tech Guides

npm / Yarn / pnpm

Complete reference guide for JavaScript package managers

1

Quick Reference

Essential Commands Side-by-Side

The most common package manager operations across npm, Yarn, and pnpm.

Task npm yarn pnpm
Install all dependencies npm install yarn install pnpm install
Install package npm install <pkg> yarn add <pkg> pnpm add <pkg>
Install dev dependency npm install -D <pkg> yarn add -D <pkg> pnpm add -D <pkg>
Install globally npm install -g <pkg> yarn global add <pkg> pnpm add -g <pkg>
Remove package npm uninstall <pkg> yarn remove <pkg> pnpm remove <pkg>
Update packages npm update yarn upgrade pnpm update
Update interactive npx npm-check-updates -u yarn upgrade-interactive pnpm update -i
List packages npm list yarn list pnpm list
Check outdated npm outdated yarn outdated pnpm outdated
Run script npm run <script> yarn <script> pnpm <script>
Execute package npx <pkg> yarn dlx <pkg> pnpm dlx <pkg>
Security audit npm audit yarn audit pnpm audit
Clean cache npm cache clean --force yarn cache clean pnpm store prune
Link local package npm link yarn link pnpm link
Initialize project npm init yarn init pnpm init
CI install npm ci yarn install --frozen-lockfile pnpm install --frozen-lockfile
2

Installation & Setup

Installing npm

npm comes bundled with Node.js. Install Node.js from nodejs.org.

# Check npm version
npm --version

# Update npm to latest version
npm install -g npm@latest

Installing Yarn

Yarn Classic (v1)

npm install -g yarn

# Verify installation
yarn --version

Yarn Berry (v2+)

# Enable Corepack (bundled with Node.js 14.19+)
corepack enable

# Set version for project
yarn set version stable

Installing pnpm

# Via npm
npm install -g pnpm

# Via standalone script (recommended)
curl -fsSL https://get.pnpm.io/install.sh | sh -

# Via Corepack
corepack enable
corepack prepare pnpm@latest --activate

# Verify installation
pnpm --version

Corepack - Package Manager Manager

Corepack is a zero-runtime-dependency Node.js script that acts as a bridge between Node.js projects and package managers. It's distributed with Node.js from version 14.19.0+.

Enable Corepack

corepack enable

Configure package manager in package.json

{
  "packageManager": "pnpm@9.1.4"
}

This ensures everyone on your team uses the exact same package manager version without manual synchronization.

Version Management

npm

npm install -g npm@8.19.0    # Install specific version
npm install -g npm@latest    # Latest stable
npm view npm versions        # List all versions

Yarn

yarn set version 3.6.0       # Set specific version
yarn set version stable      # Latest stable
yarn set version berry       # Latest v2+

pnpm

pnpm env use --global 18     # Use Node.js 18
pnpm env use --global lts    # Use LTS version
pnpm env list               # List installed versions
3

Package Management

Installing Packages

Install all dependencies

npm install              # npm
yarn install             # yarn
pnpm install            # pnpm

# Alternative short forms
npm i
yarn
pnpm i

Install specific package

npm install react react-dom
yarn add react react-dom
pnpm add react react-dom

# With version specifiers
npm install lodash@4.17.21
yarn add lodash@4.17.21
pnpm add lodash@4.17.21

# Latest version
npm install lodash@latest
yarn add lodash@latest
pnpm add lodash@latest

Install as dev dependency

npm install -D eslint prettier
yarn add -D eslint prettier
pnpm add -D eslint prettier

# Long form
npm install --save-dev eslint

Install globally

npm install -g typescript
yarn global add typescript
pnpm add -g typescript

# List global packages
npm list -g --depth=0
yarn global list
pnpm list -g

Install from different sources

# GitHub repository
npm install user/repo
pnpm add user/repo

# Git URL
npm install git+https://github.com/user/repo.git
pnpm add git+https://github.com/user/repo.git

# Local file path
npm install file:../local-package
pnpm add file:../local-package

# Tarball URL
npm install https://example.com/package.tgz

Removing Packages

npm uninstall lodash
yarn remove lodash
pnpm remove lodash

# Remove global package
npm uninstall -g typescript
yarn global remove typescript
pnpm remove -g typescript

# Remove and update lock file
npm uninstall --package-lock-only lodash

Updating Packages

Update within semver range

npm update                    # Update all packages
yarn upgrade                 # Update all packages
pnpm update                  # Update all packages

# Update specific package
npm update react
yarn upgrade react
pnpm update react

Update to latest (breaking semver)

npm install react@latest
yarn upgrade react@latest
pnpm update react@latest

# Interactive update (choose which to update)
yarn upgrade-interactive
pnpm update -i

# Using npm-check-updates
npx npm-check-updates -u     # Update package.json
npm install                  # Install updated versions

Listing Packages

# List installed packages
npm list
yarn list
pnpm list

# List top-level only
npm list --depth=0
yarn list --depth=0
pnpm list --depth=0

# List specific package
npm list react
pnpm list react

# List in JSON format
npm list --json
pnpm list --json

Checking Outdated Packages

npm outdated
yarn outdated
pnpm outdated

Shows table with:

  • Package name
  • Current version
  • Wanted version (max in semver range)
  • Latest version (most recent)
  • Location in dependency tree

Security Audit

npm

npm audit                    # View vulnerabilities
npm audit --json            # JSON output
npm audit fix               # Auto-fix compatible updates
npm audit fix --force       # Force major version updates
npm audit signatures        # Verify package signatures

Yarn

yarn audit                   # View vulnerabilities
yarn audit --json
yarn npm audit              # Yarn Berry

pnpm

pnpm audit                   # View vulnerabilities
pnpm audit --json
pnpm audit --fix            # Auto-fix vulnerabilities
Important: npm audit fix only updates packages within your declared semver ranges. For major version upgrades, use --force (use with caution).

Package Funding Information

npm fund                     # Show funding info for all packages
npm fund <package>          # Open funding URL for specific package

# Suppress funding messages
npm install --no-fund
npm set fund=false          # Disable globally in .npmrc

The npm fund command displays packages looking for funding and links to support pages (GitHub Sponsors, Open Collective, etc.).

4

Scripts & Running

Defining Scripts

In package.json:

{
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js",
    "build": "webpack --mode production",
    "test": "jest",
    "lint": "eslint src/",
    "format": "prettier --write src/"
  }
}

Running Scripts

# npm requires 'run' for custom scripts
npm run dev
npm run build

# Some scripts don't need 'run'
npm start
npm test

# yarn doesn't require 'run'
yarn dev
yarn build
yarn start
yarn test

# pnpm similar to npm
pnpm dev
pnpm run build
pnpm start
pnpm test

Passing Arguments to Scripts

npm run test -- --watch
yarn test --watch
pnpm test -- --watch

# Example with environment variables
npm run build -- --env production

Execute Package Binaries

npx (npm)

npx create-react-app my-app
npx eslint src/
npx -p typescript tsc --init

# Execute specific version
npx cowsay@1.5.0 "Hello"

# Execute from URL
npx https://gist.github.com/user/script.js

# Execute local binary
npx -c 'tsc && node dist/index.js'

yarn dlx (Yarn Berry)

yarn dlx create-react-app my-app
yarn dlx eslint src/

# Execute package without installation
yarn dlx -p typescript tsc --init

pnpm dlx

pnpm dlx create-react-app my-app
pnpm dlx eslint src/

# Execute with specific version
pnpm dlx cowsay@1.5.0 "Hello"

All three (npx, yarn dlx, pnpm dlx) download and execute packages in a temporary environment without globally installing them.

Lifecycle Scripts & Hooks

npm runs lifecycle scripts at various stages. Any script can have pre and post versions.

Available lifecycle scripts

  • prepare - Runs after npm install and before npm publish
  • prepublish - Deprecated, use prepublishOnly
  • prepublishOnly - Runs BEFORE package is prepared/packed, ONLY on npm publish
  • prepack - Runs BEFORE tarball is packed
  • postpack - Runs AFTER tarball is generated
  • preinstall - Runs before package is installed
  • postinstall - Runs after package is installed

Pre and Post hooks

{
  "scripts": {
    "pretest": "eslint src/",
    "test": "jest",
    "posttest": "echo 'Tests complete'",

    "prebuild": "npm run clean",
    "build": "webpack",
    "postbuild": "npm run deploy"
  }
}

When you run npm test, it automatically runs:

  1. pretest
  2. test
  3. posttest

Publishing lifecycle

# When running: npm publish
# Execution order:
prepublishOnly → prepare → prepack → pack → postpack → publish → postpublish
5

Dependencies

Dependency Types

dependencies

Packages required for your code to run in production:

{
  "dependencies": {
    "react": "^18.2.0",
    "express": "^4.18.2"
  }
}

Installed with:

npm install react
yarn add react
pnpm add react

devDependencies

Packages needed only during development (testing, building, linting):

{
  "devDependencies": {
    "eslint": "^8.45.0",
    "jest": "^29.6.0",
    "webpack": "^5.88.0"
  }
}

Installed with:

npm install -D eslint
yarn add -D eslint
pnpm add -D eslint

To skip devDependencies during install:

npm install --production
yarn install --production
pnpm install --prod

peerDependencies

Packages your library expects to be installed by the consumer:

{
  "peerDependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}
Important:
• npm v3-v6: peerDependencies were NOT auto-installed
• npm v7+: peerDependencies ARE auto-installed by default
• Use --legacy-peer-deps to revert to old behavior
• pnpm handles peer dependencies strictly by default

optionalDependencies

Packages that enhance functionality but aren't required:

{
  "optionalDependencies": {
    "fsevents": "^2.3.2"
  }
}

Skip installing:

npm install --no-optional
pnpm install --no-optional

bundledDependencies

Array of package names bundled with your package when published:

{
  "bundledDependencies": ["package-a", "package-b"]
}

Dependency Installation Flags

# Omit specific dependency types
npm install --omit=dev              # Skip devDependencies
npm install --omit=optional         # Skip optionalDependencies
npm install --omit=peer            # Skip peerDependencies

# Legacy peer dependency handling
npm install --legacy-peer-deps     # Ignore peer dependency conflicts

# Force install (bypass cache and conflicts)
npm install --force

# Production only
npm install --production
npm install --omit=dev

Overrides & Resolutions

Force specific versions of nested dependencies.

npm (v8.3+)

{
  "overrides": {
    "lodash": "4.17.21",
    "foo": {
      "bar": "1.0.0"
    },
    "bar@2.0.0": "3.0.0"
  }
}

Yarn

{
  "resolutions": {
    "lodash": "4.17.21",
    "**/lodash": "4.17.21",
    "foo/**/bar": "1.0.0"
  }
}

pnpm

{
  "pnpm": {
    "overrides": {
      "lodash": "4.17.21",
      "foo>bar": "1.0.0"
    }
  }
}

pnpm also supports resolutions for Yarn migration compatibility. If both exist, pnpm.overrides takes precedence.

Important: After changing overrides, delete node_modules and lock files, then reinstall to recalculate the dependency graph.

Lock Files

Lock files ensure deterministic, reproducible installs across environments.

Package Manager Lock File Format
npm package-lock.json JSON
Yarn Classic yarn.lock Custom
Yarn Berry yarn.lock YAML-like
pnpm pnpm-lock.yaml YAML

Best practices

  • Always commit lock files to version control
  • Never mix package managers (causes version mismatches)
  • Don't manually edit lock files
  • Use npm ci / pnpm install --frozen-lockfile in CI/CD

Lock file integrity

All lock files include cryptographic hashes (checksums) to verify package integrity:

  • npm uses SHA-512 hashes
  • Yarn uses SHA-512 hashes
  • pnpm uses SHA-512 hashes

If downloaded package hash doesn't match the lock file, installation fails (prevents malicious code injection).

Handling integrity check failures

# Yarn
yarn install --update-checksums

# Delete lock file and reinstall (last resort)
rm package-lock.json
npm install
6

Workspaces & Monorepos

npm Workspaces

package.json (root):

{
  "name": "my-monorepo",
  "private": true,
  "workspaces": [
    "packages/*",
    "apps/*"
  ]
}

Commands

# Install all workspace dependencies
npm install

# Run script in specific workspace
npm run build --workspace=packages/ui

# Run script in all workspaces
npm run test --workspaces

# Add dependency to specific workspace
npm install react --workspace=packages/ui

# Add dependency to root
npm install -D typescript -w

Yarn Workspaces

package.json (root):

{
  "private": true,
  "workspaces": [
    "packages/*",
    "apps/*"
  ]
}

Commands

# Install all dependencies
yarn install

# Run command in workspace
yarn workspace @myorg/ui build

# Run command in all workspaces
yarn workspaces run build

# Add dependency to workspace
yarn workspace @myorg/ui add react

# List workspaces
yarn workspaces list

pnpm Workspaces

pnpm-workspace.yaml (root):

packages:
  - 'packages/*'
  - 'apps/*'
  - '!**/test/**'

package.json (workspace package):

{
  "name": "@myorg/ui",
  "dependencies": {
    "@myorg/utils": "workspace:*"
  }
}

Commands

# Install all workspace dependencies
pnpm install

# Run command in specific workspace
pnpm --filter @myorg/ui build

# Run command in all workspaces
pnpm -r build

# Add dependency to workspace
pnpm --filter @myorg/ui add react

# Add local workspace dependency
pnpm --filter @myorg/ui add @myorg/utils@workspace:*

# List workspaces
pnpm list -r --depth -1

Workspace Protocol

pnpm introduced the workspace: protocol for linking local packages:

{
  "dependencies": {
    "@myorg/shared": "workspace:*",
    "@myorg/utils": "workspace:^1.0.0"
  }
}

Benefits

  • Local packages linked during development
  • Published packages use actual version numbers (not workspace:*)
  • Prevents accidental publishing with local paths

Hoisting in Monorepos

npm: Automatically hoists common dependencies to root node_modules

Yarn: Berry uses Plug'n'Play by default (no hoisting needed)

pnpm: Uses symlinks; hoisting configuration in .npmrc:

hoist=true
hoist-pattern[]=*eslint*
hoist-pattern[]=*prettier*

Best practices for monorepos

  • Prefer workspace:* for internal links
  • Hoist common devDependencies to root
  • Pin critical versions (e.g., React)
  • Use peer dependencies for shared libraries
7

Publishing

Preparing to Publish

1. Create npm account

npm adduser
# or
npm login

2. Configure package.json

{
  "name": "my-package",
  "version": "1.0.0",
  "description": "A useful package",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": [
    "dist",
    "README.md",
    "LICENSE"
  ],
  "keywords": ["javascript", "utility"],
  "author": "Your Name <you@example.com>",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/user/repo.git"
  },
  "bugs": "https://github.com/user/repo/issues",
  "homepage": "https://github.com/user/repo#readme"
}

3. Test package locally

npm pack
# Creates: my-package-1.0.0.tgz

Semantic Versioning

Version format: MAJOR.MINOR.PATCH

  • MAJOR (1.x.x): Breaking changes
  • MINOR (x.1.x): New features (backward compatible)
  • PATCH (x.x.1): Bug fixes (backward compatible)

Bumping versions

npm version patch       # 1.0.0 → 1.0.1
npm version minor       # 1.0.1 → 1.1.0
npm version major       # 1.1.0 → 2.0.0

# Pre-release versions
npm version prerelease  # 1.0.0 → 1.0.1-0
npm version prepatch    # 1.0.0 → 1.0.1-0
npm version preminor    # 1.0.0 → 1.1.0-0
npm version premajor    # 1.0.0 → 2.0.0-0

# With custom pre-release identifier
npm version prerelease --preid=alpha  # 1.0.0 → 1.0.1-alpha.0
npm version prerelease --preid=beta   # 1.0.1-alpha.0 → 1.0.1-beta.0

The npm version command:

  • Updates version in package.json and package-lock.json
  • Creates a git commit
  • Creates a git tag (e.g., v1.0.1)

Publishing Packages

Public package

npm publish

Scoped package (public)

npm publish --access public

Scoped packages use format @username/package-name or @org/package-name:

{
  "name": "@myorg/my-package"
}

Pre-release publishing

# Publish with 'beta' tag
npm publish --tag beta

# Users install with:
npm install my-package@beta

Distribution tags

# Add tag
npm dist-tag add my-package@1.0.1 stable

# Remove tag
npm dist-tag rm my-package beta

# List tags
npm dist-tag ls my-package

Unpublishing

# Unpublish specific version
npm unpublish my-package@1.0.0

# Unpublish entire package (within 72 hours)
npm unpublish my-package --force
Important: You can only unpublish packages within 72 hours of publishing. After that, deprecate instead:
npm deprecate my-package@1.0.0 "This version has critical bugs"

npm link - Local Development

Test package locally before publishing:

# In package directory
cd ~/projects/my-package
npm link

# In project using the package
cd ~/projects/my-app
npm link my-package

# Unlink
npm unlink my-package

# Unlink global
npm unlink -g my-package

Yarn link

yarn link
yarn link my-package
yarn unlink my-package

pnpm link

pnpm link --global
pnpm link --global my-package

# Or direct directory link
pnpm link ~/projects/my-package
Important: npm link can cause issues with peer dependencies and package duplication. For more stable local testing, consider:
file: protocol: npm install file:../my-package
• Tools like yalc
8

Configuration

.npmrc Configuration Files

npm config files use INI format with key=value pairs.

File locations (priority order)

  1. Project .npmrc (repo root, next to package.json)
  2. User ~/.npmrc
  3. Global /etc/npmrc
  4. Built-in npm defaults

Common settings

# Registry
registry=https://registry.npmjs.org/

# Scoped registry
@myorg:registry=https://npm.pkg.github.com/

# Authentication token (use environment variable)
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

# Save exact versions (no ^ or ~)
save-exact=true

# Disable package-lock.json
package-lock=false

# Disable funding messages
fund=false

# Set log level
loglevel=warn

# Proxy settings
proxy=http://proxy.example.com:8080/
https-proxy=http://proxy.example.com:8080/

# Cache location
cache=/path/to/cache

# Node version engine-strict
engine-strict=true

Scoping authentication to registries

//registry.npmjs.org/:_authToken=${NPM_TOKEN}
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
@mycompany:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}

Comments in .npmrc

; This is a comment
# This is also a comment
registry=https://registry.npmjs.org/

.yarnrc.yml Configuration (Yarn Berry)

nodeLinker: node-modules
# or
nodeLinker: pnp

yarnPath: .yarn/releases/yarn-3.6.0.cjs

npmRegistryServer: "https://registry.npmjs.org"

npmScopes:
  myorg:
    npmRegistryServer: "https://npm.pkg.github.com"
    npmAuthToken: "${GITHUB_TOKEN}"

enableGlobalCache: false

compressionLevel: mixed

enableTelemetry: false

pnpm Configuration

pnpm uses .npmrc with additional pnpm-specific settings:

# Store location
store-dir=~/.pnpm-store

# Symlink handling
symlink=true

# Strict peer dependencies
strict-peer-dependencies=true

# Shamefully hoist (like npm)
shamefully-hoist=false

# Auto install peers
auto-install-peers=true

# Lockfile version
lockfile-version=6.0

package.json Configuration Fields

Essential fields

{
  "name": "my-package",
  "version": "1.0.0",
  "description": "Package description",
  "main": "dist/index.js",
  "module": "dist/index.esm.js",
  "types": "dist/index.d.ts",
  "exports": {
    ".": {
      "import": "./dist/index.esm.js",
      "require": "./dist/index.js",
      "types": "./dist/index.d.ts"
    }
  },
  "files": ["dist", "README.md"],
  "scripts": {},
  "keywords": [],
  "author": "",
  "license": "MIT"
}

Engine requirements

{
  "engines": {
    "node": ">=18.0.0",
    "npm": ">=9.0.0"
  }
}

Package manager enforcement (Corepack)

{
  "packageManager": "pnpm@9.1.4"
}

Publishing configuration

{
  "publishConfig": {
    "access": "public",
    "registry": "https://registry.npmjs.org/"
  }
}

Setting Config Values via CLI

# npm
npm config set registry https://registry.npmjs.org/
npm config get registry
npm config delete registry
npm config list
npm config edit

# Yarn
yarn config set npmRegistryServer "https://registry.npmjs.org"
yarn config get npmRegistryServer

# pnpm
pnpm config set registry https://registry.npmjs.org/
pnpm config get registry
pnpm config list
9

Security

npm audit

Check for known vulnerabilities:

npm audit                     # Display vulnerabilities
npm audit --json             # JSON output
npm audit --parseable        # Machine-readable output

# Filter by severity
npm audit --audit-level=moderate
npm audit --audit-level=high

# Fix vulnerabilities
npm audit fix                # Auto-fix (semver compatible)
npm audit fix --force        # Force major version updates

# Verify package signatures
npm audit signatures

Output categories

  • Low: Minimal risk
  • Moderate: Some risk
  • High: Significant risk
  • Critical: Immediate action required

Important limitations

  • npm audit fix only updates within semver ranges
  • Won't detect newly compromised packages
  • Only checks against public vulnerability database (CVE)
  • May show false positives for devDependencies

Yarn audit

yarn audit                    # Check vulnerabilities
yarn audit --json
yarn npm audit               # Yarn Berry

# No auto-fix in Yarn Classic
# Use yarn upgrade for manual fixes

pnpm audit

pnpm audit                    # Check vulnerabilities
pnpm audit --json
pnpm audit --fix             # Auto-fix vulnerabilities
pnpm audit --audit-level=high

Lock File Integrity

Lock files verify package integrity using SHA-512 checksums.

How it works

  1. Package downloaded from registry
  2. SHA-512 hash calculated
  3. Hash compared to lock file
  4. Install fails if mismatch

Handling checksum failures

# Yarn
yarn install --update-checksums

# npm/pnpm - delete lock file and reinstall
rm package-lock.json
npm install

Supply Chain Security Best Practices

  1. Always commit lock files - Ensures reproducible builds
  2. Enable 2FA on npm account - Prevents account takeover
  3. Use npm ci in CI/CD - Installs exact versions from lock file
  4. Review dependency updates - Don't blindly update
  5. Monitor for vulnerabilities - Integrate npm audit in CI
  6. Verify package ownership - Check package author/maintainer
  7. Use scoped packages - Better control over namespace
  8. Audit build artifacts - Review what gets published

Software Bill of Materials (SBOM)

An SBOM is a nested inventory listing all components, libraries, and modules in software.

Purpose

  • Track software elements
  • Identify vulnerabilities
  • Mitigate supply chain risks
  • Regulatory compliance

Standard formats

  • SPDX - License tracking
  • CycloneDX - Security and vulnerability analysis
  • SWID - IT asset management

Generate SBOM

# Using CycloneDX
npx @cyclonedx/cyclonedx-npm --output-file sbom.json

# Using SPDX
npm install -g @spdx/spdx-sbom-generator
spdx-sbom-generator -p .

Why SBOMs matter

  • Required by U.S. federal agencies
  • Transparency into nested dependencies
  • Faster vulnerability remediation
  • Supply chain attack prevention
High-profile supply chain attacks:
SolarWinds (2020) - Malicious code in software updates, 18,000+ orgs affected
Log4j (2021) - Vulnerability in widely-used library, hundreds of millions of devices affected

SBOMs help map all components, including deeply nested libraries, enabling faster vulnerability discovery and remediation.

10

Pro Tips

Performance Comparison (2026)

Installation Speed (cold install, React + TypeScript project)

  • Bun: 18x faster than npm
  • pnpm: 3.4x faster than npm
  • Yarn: 2.1x faster than npm
  • npm: Baseline

Real-world benchmarks

  • pnpm: 70% faster installs, 48% faster CI builds vs npm
  • First installs: pnpm 30-50% faster
  • Repeat installs: pnpm shows even greater speed (efficient caching)

Disk Space Savings

  • pnpm: 70-80% reduction in multi-project setups
  • npm/Yarn: Each project has full copy of dependencies
  • pnpm: Global content-addressable store + hard links
Example:
100 projects using lodash
• npm: 100 copies of lodash on disk
• pnpm: 1 copy in global store, 100 hard links

When to Use Which Package Manager

Use npm when:

  • Working on existing npm projects
  • Need maximum compatibility
  • Prefer official, conservative tooling
  • Simple single-package projects

Use Yarn when:

  • Using Plug'n'Play for zero-install workflows
  • Need advanced workspace features
  • Prefer Yarn's UX and error messages
  • Working on Yarn projects

Use pnpm when:

  • Managing monorepos
  • Need maximum performance
  • Want disk space savings
  • Strict dependency management required
  • Multi-project development environments
Summary:
npm: Most compatible, most conservative
Yarn: Best UX, Plug'n'Play innovation
pnpm: Fastest, most efficient, best for monorepos

Caching & Offline Mode

npm

# Check cache
npm cache verify

# Clean cache
npm cache clean --force

# Use cache only (offline)
npm install --prefer-offline

# Strict offline mode
npm install --offline

Yarn

# Cache location
yarn cache dir

# Clean cache
yarn cache clean

# Offline mirror (commit to Git)
# .yarnrc.yml
yarn-offline-mirror "./yarn-offline-mirror"

pnpm

# Verify store
pnpm store status

# Prune unreferenced packages
pnpm store prune

# pnpm automatically uses cache when offline
pnpm install

Cache locations

  • npm: ~/.npm
  • Yarn: ~/.yarn/berry/cache (Berry) or ~/.cache/yarn (Classic)
  • pnpm: ~/.pnpm-store

CI/CD Best Practices

Use exact lock file installations

# npm
npm ci                                    # Fast, clean install from lock file

# Yarn
yarn install --frozen-lockfile           # Fail if lock file is outdated
yarn install --immutable                 # Yarn Berry

# pnpm
pnpm install --frozen-lockfile           # Fail if lock file needs update

Cache package manager stores

# GitHub Actions example
- name: Setup Node
  uses: actions/setup-node@v3
  with:
    node-version: '18'
    cache: 'pnpm'

# Manual cache
- uses: actions/cache@v3
  with:
    path: ~/.pnpm-store
    key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}

Speed up CI with pnpm

  • Content-addressable cache shared across CI runs
  • Hard links eliminate duplicate downloads
  • Dramatically faster than npm/Yarn in CI

Commit offline cache (Yarn Berry)

# .yarnrc.yml
enableGlobalCache: false

Then commit .yarn/cache to Git for zero-install workflows (no yarn install needed in CI).

Advanced Tips & Tricks

Alias npm commands

# Add to ~/.bashrc or ~/.zshrc
alias ni="npm install"
alias nid="npm install -D"
alias nig="npm install -g"
alias nt="npm test"
alias nb="npm run build"

Check package size before installing

npm info lodash
npx package-size lodash

Find which package depends on a package

npm ls react
pnpm why react
yarn why react

Interactive dependency updates

# Yarn
yarn upgrade-interactive --latest

# pnpm
pnpm update -i --latest

# npm (using ncm)
npx npm-check-updates -i

Generate package-lock.json from yarn.lock (or vice versa)

npx synp --source-file yarn.lock
npx synp --source-file package-lock.json

Prevent accidental publishing

{
  "private": true
}

Run script before every install

{
  "scripts": {
    "preinstall": "node check-node-version.js"
  }
}

Workspace-specific commands

# npm
npm run test --workspace=@myorg/ui

# pnpm
pnpm --filter @myorg/ui test

# Run in all workspaces matching pattern
pnpm --filter "./packages/**" build

Parallel execution in workspaces

# pnpm (parallel by default)
pnpm -r build

# npm (sequential by default, use --workspaces)
npm run build --workspaces

Deduplicate dependencies

npm dedupe
yarn dedupe
pnpm dedupe

Check for duplicate dependencies

npx depcheck
npx npm-check

Analyze bundle size impact

npx bundlephobia lodash
npx cost-of-modules

Global package locations

npm root -g          # Global node_modules location
npm list -g --depth=0    # List global packages
npm bin -g           # Global bin location

Use newer package manager features

# Corepack (comes with Node.js 14.19+)
corepack enable
corepack prepare pnpm@latest --activate

# Now pnpm is available without global install
pnpm --version

Migrate from npm to pnpm

pnpm import          # Generates pnpm-lock.yaml from package-lock.json
rm package-lock.json
rm -rf node_modules
pnpm install

Migrate from Yarn to pnpm

pnpm import          # Also works with yarn.lock
rm yarn.lock
rm -rf node_modules
pnpm install

Check package health

npx snyk test        # Security vulnerabilities
npx license-checker  # License compliance
npx depcheck        # Unused dependencies