Complete reference guide for JavaScript package managers
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 |
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
npm install -g yarn
# Verify installation
yarn --version
# Enable Corepack (bundled with Node.js 14.19+)
corepack enable
# Set version for project
yarn set version stable
# 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 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+.
corepack enable
{
"packageManager": "pnpm@9.1.4"
}
This ensures everyone on your team uses the exact same package manager version without manual synchronization.
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 set version 3.6.0 # Set specific version
yarn set version stable # Latest stable
yarn set version berry # Latest v2+
pnpm env use --global 18 # Use Node.js 18
pnpm env use --global lts # Use LTS version
pnpm env list # List installed versions
npm install # npm
yarn install # yarn
pnpm install # pnpm
# Alternative short forms
npm i
yarn
pnpm i
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
npm install -D eslint prettier
yarn add -D eslint prettier
pnpm add -D eslint prettier
# Long form
npm install --save-dev eslint
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
# 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
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
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
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
# 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
npm outdated
yarn outdated
pnpm outdated
Shows table with:
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 audit # View vulnerabilities
yarn audit --json
yarn npm audit # Yarn Berry
pnpm audit # View vulnerabilities
pnpm audit --json
pnpm audit --fix # Auto-fix vulnerabilities
npm audit fix only updates packages within your declared semver ranges. For major version upgrades, use --force (use with caution).
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.).
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/"
}
}
# 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
npm run test -- --watch
yarn test --watch
pnpm test -- --watch
# Example with environment variables
npm run build -- --env production
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 create-react-app my-app
yarn dlx eslint src/
# Execute package without installation
yarn dlx -p typescript tsc --init
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.
npm runs lifecycle scripts at various stages. Any script can have pre and post versions.
prepare - Runs after npm install and before npm publishprepublish - Deprecated, use prepublishOnlyprepublishOnly - Runs BEFORE package is prepared/packed, ONLY on npm publishprepack - Runs BEFORE tarball is packedpostpack - Runs AFTER tarball is generatedpreinstall - Runs before package is installedpostinstall - Runs after package is installed{
"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:
pretesttestposttest# When running: npm publish
# Execution order:
prepublishOnly → prepare → prepack → pack → postpack → publish → postpublish
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
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
Packages your library expects to be installed by the consumer:
{
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
--legacy-peer-deps to revert to old behaviorPackages that enhance functionality but aren't required:
{
"optionalDependencies": {
"fsevents": "^2.3.2"
}
}
Skip installing:
npm install --no-optional
pnpm install --no-optional
Array of package names bundled with your package when published:
{
"bundledDependencies": ["package-a", "package-b"]
}
# 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
Force specific versions of nested dependencies.
{
"overrides": {
"lodash": "4.17.21",
"foo": {
"bar": "1.0.0"
},
"bar@2.0.0": "3.0.0"
}
}
{
"resolutions": {
"lodash": "4.17.21",
"**/lodash": "4.17.21",
"foo/**/bar": "1.0.0"
}
}
{
"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.
node_modules and lock files, then reinstall to recalculate the dependency graph.
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 |
npm ci / pnpm install --frozen-lockfile in CI/CDAll lock files include cryptographic hashes (checksums) to verify package integrity:
If downloaded package hash doesn't match the lock file, installation fails (prevents malicious code injection).
# Yarn
yarn install --update-checksums
# Delete lock file and reinstall (last resort)
rm package-lock.json
npm install
package.json (root):
{
"name": "my-monorepo",
"private": true,
"workspaces": [
"packages/*",
"apps/*"
]
}
# 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
package.json (root):
{
"private": true,
"workspaces": [
"packages/*",
"apps/*"
]
}
# 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-workspace.yaml (root):
packages:
- 'packages/*'
- 'apps/*'
- '!**/test/**'
package.json (workspace package):
{
"name": "@myorg/ui",
"dependencies": {
"@myorg/utils": "workspace:*"
}
}
# 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
pnpm introduced the workspace: protocol for linking local packages:
{
"dependencies": {
"@myorg/shared": "workspace:*",
"@myorg/utils": "workspace:^1.0.0"
}
}
workspace:*)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*
workspace:* for internal linksnpm adduser
# or
npm login
{
"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"
}
npm pack
# Creates: my-package-1.0.0.tgz
Version format: MAJOR.MINOR.PATCH
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:
version in package.json and package-lock.jsonv1.0.1)npm publish
npm publish --access public
Scoped packages use format @username/package-name or @org/package-name:
{
"name": "@myorg/my-package"
}
# Publish with 'beta' tag
npm publish --tag beta
# Users install with:
npm install my-package@beta
# 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
# Unpublish specific version
npm unpublish my-package@1.0.0
# Unpublish entire package (within 72 hours)
npm unpublish my-package --force
npm deprecate my-package@1.0.0 "This version has critical bugs"
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 my-package
yarn unlink my-package
pnpm link --global
pnpm link --global my-package
# Or direct directory link
pnpm link ~/projects/my-package
npm link can cause issues with peer dependencies and package duplication. For more stable local testing, consider:file: protocol: npm install file:../my-packagenpm config files use INI format with key=value pairs.
.npmrc (repo root, next to package.json)~/.npmrc/etc/npmrc# 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
//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}
; This is a comment
# This is also a comment
registry=https://registry.npmjs.org/
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 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
{
"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"
}
{
"engines": {
"node": ">=18.0.0",
"npm": ">=9.0.0"
}
}
{
"packageManager": "pnpm@9.1.4"
}
{
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
}
}
# 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
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
npm audit fix only updates within semver rangesyarn 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 # Check vulnerabilities
pnpm audit --json
pnpm audit --fix # Auto-fix vulnerabilities
pnpm audit --audit-level=high
Lock files verify package integrity using SHA-512 checksums.
# Yarn
yarn install --update-checksums
# npm/pnpm - delete lock file and reinstall
rm package-lock.json
npm install
npm ci in CI/CD - Installs exact versions from lock filenpm audit in CIAn SBOM is a nested inventory listing all components, libraries, and modules in software.
# Using CycloneDX
npx @cyclonedx/cyclonedx-npm --output-file sbom.json
# Using SPDX
npm install -g @spdx/spdx-sbom-generator
spdx-sbom-generator -p .
SBOMs help map all components, including deeply nested libraries, enabling faster vulnerability discovery and remediation.
# 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
# Cache location
yarn cache dir
# Clean cache
yarn cache clean
# Offline mirror (commit to Git)
# .yarnrc.yml
yarn-offline-mirror "./yarn-offline-mirror"
# Verify store
pnpm store status
# Prune unreferenced packages
pnpm store prune
# pnpm automatically uses cache when offline
pnpm install
~/.npm~/.yarn/berry/cache (Berry) or ~/.cache/yarn (Classic)~/.pnpm-store# 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
# 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') }}
# .yarnrc.yml
enableGlobalCache: false
Then commit .yarn/cache to Git for zero-install workflows (no yarn install needed in CI).
# 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"
npm info lodash
npx package-size lodash
npm ls react
pnpm why react
yarn why react
# Yarn
yarn upgrade-interactive --latest
# pnpm
pnpm update -i --latest
# npm (using ncm)
npx npm-check-updates -i
npx synp --source-file yarn.lock
npx synp --source-file package-lock.json
{
"private": true
}
{
"scripts": {
"preinstall": "node check-node-version.js"
}
}
# npm
npm run test --workspace=@myorg/ui
# pnpm
pnpm --filter @myorg/ui test
# Run in all workspaces matching pattern
pnpm --filter "./packages/**" build
# pnpm (parallel by default)
pnpm -r build
# npm (sequential by default, use --workspaces)
npm run build --workspaces
npm dedupe
yarn dedupe
pnpm dedupe
npx depcheck
npx npm-check
npx bundlephobia lodash
npx cost-of-modules
npm root -g # Global node_modules location
npm list -g --depth=0 # List global packages
npm bin -g # Global bin location
# Corepack (comes with Node.js 14.19+)
corepack enable
corepack prepare pnpm@latest --activate
# Now pnpm is available without global install
pnpm --version
pnpm import # Generates pnpm-lock.yaml from package-lock.json
rm package-lock.json
rm -rf node_modules
pnpm install
pnpm import # Also works with yarn.lock
rm yarn.lock
rm -rf node_modules
pnpm install
npx snyk test # Security vulnerabilities
npx license-checker # License compliance
npx depcheck # Unused dependencies