Toolmingo
Guides13 min read

npm Cheat Sheet: Every Command You Actually Use

A complete npm cheat sheet covering install, scripts, versioning, workspaces, publishing, and audit. Quick reference for every Node.js developer.

Every npm command you reach for daily — and the ones you always have to look up. This covers init, install, scripts, versioning, workspaces, and publishing.

Quick reference

The 25 commands that cover 95% of daily npm work.

Command What it does
npm init -y Create package.json with defaults
npm install Install all dependencies
npm install <pkg> Install and add to dependencies
npm install -D <pkg> Install as devDependency
npm install -g <pkg> Install globally
npm install --save-exact <pkg> Install exact version (no ^)
npm uninstall <pkg> Remove package
npm update Update packages to latest semver
npm update <pkg> Update one package
npm outdated List outdated packages
npm run <script> Run a script from package.json
npm test Shorthand for npm run test
npm start Shorthand for npm run start
npm ci Clean install from lockfile
npm list List installed packages
npm list --depth=0 List top-level packages only
npm info <pkg> Show package metadata
npm view <pkg> versions List all published versions
npm audit Check for vulnerabilities
npm audit fix Auto-fix vulnerabilities
npm dedupe Remove duplicate packages
npm cache clean --force Clear npm cache
npm login Authenticate with npm registry
npm publish Publish package to registry
npx <cmd> Run a package without installing

Initialisation

Create a new project

# Interactive (asks questions)
npm init

# Accept all defaults
npm init -y

# With a template
npm init react-app my-app
npm init vite@latest my-app -- --template react-ts

package.json key fields

{
  "name": "my-package",
  "version": "1.0.0",
  "description": "What it does",
  "main": "index.js",           // CJS entry point
  "module": "dist/index.mjs",   // ESM entry point
  "exports": {                  // Modern entry point map
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs"
    }
  },
  "scripts": {
    "build": "tsc",
    "dev": "nodemon src/index.js",
    "test": "jest",
    "lint": "eslint src/"
  },
  "keywords": ["node", "utility"],
  "author": "Your Name <you@example.com>",
  "license": "MIT",
  "dependencies": {},
  "devDependencies": {},
  "peerDependencies": {},       // Required by consumer, not bundled
  "engines": {
    "node": ">=18.0.0",
    "npm": ">=9.0.0"
  },
  "files": ["dist/", "README.md"],  // Files included in npm publish
  "private": true               // Prevents accidental publish
}

Installing packages

Install commands

# Add to dependencies (default)
npm install express
npm install express@4.18.2      # Exact version
npm install express@latest       # Latest tag

# Add to devDependencies
npm install -D typescript jest
npm install --save-dev typescript

# Add to peerDependencies (manually edit package.json, or)
npm install --save-peer react

# Install globally (CLI tools)
npm install -g typescript
npm install -g @vue/cli

# Install from various sources
npm install ./local-package      # Local folder
npm install github:user/repo     # GitHub repo
npm install github:user/repo#branch  # Specific branch/commit
npm install https://example.com/pkg.tgz  # Tarball URL

Install flags

Flag Short What it does
--save-dev -D Add to devDependencies
--save-exact -E Save exact version (no ^)
--global -g Install globally
--no-save Install but don't update package.json
--dry-run Show what would be installed
--prefer-offline Use cache if available
--legacy-peer-deps Ignore peer dependency conflicts
--force -f Force re-fetch even if cached

npm ci vs npm install

# Development: use npm install
# — updates package-lock.json
# — allows semver range resolution
npm install

# CI/CD and production: use npm ci
# — requires package-lock.json
# — deletes node_modules first
# — fails if lock file doesn't match package.json
# — never writes to package.json or lock file
npm ci

Removing and updating packages

# Remove a package
npm uninstall express
npm uninstall -g typescript       # Remove global package

# Update packages
npm update                        # All packages within semver range
npm update express                # One package
npm update --save                 # Also update version in package.json

# Check what's outdated
npm outdated

# Example output:
# Package   Current  Wanted   Latest  Location
# express   4.17.0   4.18.2   4.18.2  my-app

# Update to latest (bypasses semver range)
npm install express@latest

Interactive update (using npm-check)

npx npm-check -u    # Interactive UI to choose updates
npx ncu -u          # npm-check-updates: update package.json ranges

npm scripts

Defining scripts

{
  "scripts": {
    "build": "tsc --project tsconfig.json",
    "dev": "nodemon --exec ts-node src/index.ts",
    "test": "jest --coverage",
    "test:watch": "jest --watch",
    "lint": "eslint src/ --ext .ts",
    "format": "prettier --write src/",
    "clean": "rm -rf dist/",
    "prepare": "husky install"
  }
}

Running scripts

npm run build
npm run test:watch

# Shorthand aliases (no 'run' needed)
npm test      # = npm run test
npm start     # = npm run start
npm stop      # = npm run stop
npm restart   # = npm run restart

# Pass arguments to the script with --
npm run test -- --watchAll=false
npm run build -- --sourceMap

Pre and post hooks

npm auto-runs pre<script> before and post<script> after any script.

{
  "scripts": {
    "prebuild": "npm run clean",
    "build": "tsc",
    "postbuild": "node scripts/copy-assets.js",

    "pretest": "npm run lint",
    "test": "jest",

    "prepare": "husky install"  // Runs after npm install
  }
}

Sequential and parallel scripts

{
  "scripts": {
    // Sequential (one after another)
    "build:all": "npm run build:client && npm run build:server",

    // Parallel (both at same time) — requires npm-run-all or &
    "dev": "npm-run-all --parallel dev:client dev:server",
    "dev:unix": "npm run dev:client & npm run dev:server",

    // Cross-platform parallel
    "dev:cross": "concurrently \"npm run dev:client\" \"npm run dev:server\""
  }
}

Install helpers: npm install -D npm-run-all concurrently

Environment variables in scripts

{
  "scripts": {
    "build": "NODE_ENV=production tsc",
    "build:win": "set NODE_ENV=production && tsc",
    "build:cross": "cross-env NODE_ENV=production tsc"
  }
}

npm install -D cross-env for cross-platform compatibility.

Semantic versioning

npm uses semver for version ranges.

Version range syntax

Specifier Example Matches
Exact 1.2.3 Only 1.2.3
Caret ^ ^1.2.3 >=1.2.3 <2.0.0 (safe updates)
Tilde ~ ~1.2.3 >=1.2.3 <1.3.0 (patch only)
Wildcard 1.2.x Any patch version
Wildcard 1.x Any minor/patch
Range >=1.0.0 <2.0.0 Explicit range
Or 1.0.0 || 2.0.0 Either version
Latest * Any version (avoid in production)

What ^ and ~ actually do

# Package installed at version 1.2.3

"^1.2.3"   # Allows 1.2.4, 1.3.0, 1.9.9 — NOT 2.0.0
"~1.2.3"   # Allows 1.2.4, 1.2.9 — NOT 1.3.0

# For versions below 1.0.0, ^ is more conservative
"^0.2.3"   # Allows 0.2.4, 0.2.9 — NOT 0.3.0
"^0.0.3"   # Only allows 0.0.3 (exact)

# Install with exact version (no range)
npm install --save-exact react
# Saves "react": "18.2.0" instead of "react": "^18.2.0"

Dist tags

npm install react@latest     # Latest stable
npm install react@next       # Pre-release / next tag
npm install react@18.2.0     # Exact version

# View available tags
npm view react dist-tags

# Set a tag on your own package
npm dist-tag add my-pkg@2.0.0-beta.1 next
npm dist-tag rm my-pkg next

package-lock.json

# Lock file records exact installed versions for reproducible installs

# Always commit package-lock.json to version control
# Never manually edit it

# Regenerate lock file
rm package-lock.json && npm install

# Check if lock file is in sync with package.json
npm ci --dry-run

# View why a package is installed
npm explain lodash
npm why lodash         # Alias

Listing and inspecting packages

# List all installed packages (deep tree)
npm list

# List only top-level packages
npm list --depth=0

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

# Check if a specific package is installed
npm list express

# Get package info from registry
npm info express
npm info express version          # Just the version
npm info express versions         # All published versions
npm view express description      # Specific field

# See all versions matching a range
npm view express@^4 version

.npmrc configuration

# ~/.npmrc  (global user settings)
# or .npmrc in project root (project settings)

# Set custom registry
registry=https://registry.npmjs.org/

# Scoped registry (e.g. private packages)
@mycompany:registry=https://npm.mycompany.com/

# Save exact versions by default (no ^ prefix)
save-exact=true

# Set default save-prefix
save-prefix=~

# Disable running scripts on install (security)
ignore-scripts=false

# Set cache directory
cache=~/.npm

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

# Authentication (for private registries)
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

npx — run without installing

# Run a package binary without installing globally
npx create-react-app my-app
npx tsc --version
npx eslint src/

# Run a specific version
npx jest@27 --version

# Run a local binary (from node_modules/.bin)
npx mocha tests/

# Create new project templates
npx create-next-app@latest my-app
npx create-vue my-app

# Run a Node.js script from a URL (be careful — trust the source!)
npx https://cdn.jsdelivr.net/gh/user/tool/run.js

Security and audit

# Scan for vulnerabilities
npm audit

# Get detailed JSON output
npm audit --json

# Auto-fix vulnerabilities (safe fixes only)
npm audit fix

# Fix including breaking changes (semver major)
npm audit fix --force

# Ignore specific advisory (use sparingly)
npm audit --audit-level=high  # Only show high/critical

# Lock a vulnerable transitive dependency
npm install depname@safe-version

Understanding audit output

# Example:
found 2 vulnerabilities (1 moderate, 1 high)
  run `npm audit fix` to fix them, or `npm audit` for details

# Severity levels:
# info < low < moderate < high < critical

npm workspaces (monorepo)

// Root package.json
{
  "name": "my-monorepo",
  "private": true,
  "workspaces": [
    "packages/*",
    "apps/*"
  ]
}
my-monorepo/
├── package.json          (root — private: true)
├── node_modules/         (shared dependencies hoisted here)
├── packages/
│   ├── utils/
│   │   └── package.json  { "name": "@myco/utils" }
│   └── ui/
│       └── package.json  { "name": "@myco/ui" }
└── apps/
    └── web/
        └── package.json  { "name": "@myco/web" }
# Install all workspace dependencies
npm install

# Run a script in a specific workspace
npm run build --workspace=packages/utils
npm run build -w packages/utils        # Short form

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

# Install a package in a specific workspace
npm install lodash -w packages/utils

# Install a local workspace package in another
npm install @myco/utils -w apps/web
# Adds "@myco/utils": "*" to apps/web/package.json

# List all workspaces
npm query .workspace

Publishing a package

# Step 1: Authenticate
npm login
npm whoami    # Verify you're logged in

# Step 2: Set version (edit package.json or use npm version)
npm version patch    # 1.0.0 → 1.0.1
npm version minor    # 1.0.0 → 1.1.0
npm version major    # 1.0.0 → 2.0.0
npm version 1.2.3    # Set specific version

# Each npm version also creates a git commit + tag automatically

# Step 3: Preview what will be published
npm pack --dry-run   # Show files that will be included
npm pack             # Create a .tgz to inspect locally

# Step 4: Publish
npm publish

# Publish with a tag (not latest)
npm publish --tag next
npm publish --tag beta

# Publish a scoped package publicly
npm publish --access public

# Step 5: Deprecate an old version
npm deprecate my-pkg@1.0.0 "Use v2 instead"

.npmignore / files field

Control what gets published:

# Option 1: .npmignore (like .gitignore, for npm publish)
node_modules/
src/
tests/
*.test.ts
.env
tsconfig.json

# Option 2: "files" field in package.json (whitelist — preferred)
{
  "files": ["dist/", "README.md", "LICENSE"]
}

Version management with npm

# View current version
node --version
npm --version

# Update npm itself
npm install -g npm@latest

# Use a specific Node.js version (requires nvm)
nvm use 20
nvm use --lts

# Check which npm scripts are available
npm run

# Re-run last failed install (useful after network errors)
npm install

Useful one-liners

# Remove node_modules and reinstall cleanly
rm -rf node_modules package-lock.json && npm install

# Check for packages with multiple versions (deduplication candidates)
npm dedupe --dry-run

# Find why node_modules is so large
du -sh node_modules/* | sort -hr | head -20   # macOS/Linux
npx cost-of-modules                            # Cross-platform

# List scripts available in the project
npm run

# Open package homepage in browser
npm home express

# Open package repository
npm repo express

# Open package bugs/issues page
npm bugs express

# Star a package (requires login)
npm star express

Common patterns

Lock down Node.js version

{
  "engines": {
    "node": ">=20.0.0",
    "npm": ">=10.0.0"
  },
  "engineStrict": true
}

Ensure specific npm version in CI

# In CI script
npm install -g npm@10
# Or pin in package.json

Use exact versions for critical dependencies

{
  "dependencies": {
    "express": "4.18.2"    // Exact, not "^4.18.2"
  }
}

Or set globally:

npm config set save-exact true

Pre-commit hook with husky

npm install -D husky lint-staged
npx husky init

# .husky/pre-commit
npx lint-staged

# package.json
{
  "lint-staged": {
    "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{json,md}": "prettier --write"
  }
}

Health check script

{
  "scripts": {
    "check": "npm audit && npm outdated && npm run test"
  }
}

Common mistakes

Mistake Problem Fix
Committing node_modules/ Huge repo, conflicts Add to .gitignore
Not committing package-lock.json Non-reproducible installs Always commit the lockfile
Using npm install in CI Can change lockfile Use npm ci in CI/CD
^ on every dependency Unexpected breaking updates Use --save-exact for critical deps
Global installs for project tools Not reproducible for team Add to devDependencies instead
npm audit fix --force blindly May install breaking versions Review changes first
Publishing without "private": true Accidental publish Add "private": true to app package.json
Mixing npm and yarn/pnpm Conflicting lockfiles Stick to one package manager per project

npm vs yarn vs pnpm

Feature npm yarn pnpm
Lockfile package-lock.json yarn.lock pnpm-lock.yaml
Install command npm install yarn pnpm install
Add package npm install pkg yarn add pkg pnpm add pkg
Run script npm run build yarn build pnpm build
Workspaces npm workspaces yarn workspaces pnpm workspaces
Disk space High (copies) High (copies) Low (hard links)
Speed Medium Fast Fastest
Plug'n'Play No Yes No
Strict mode No No Yes (by default)

FAQ

npm install vs npm ci — when to use each?

Use npm install in development (it updates package-lock.json and resolves new versions). Use npm ci in CI/CD and deployment (it's faster, requires the lockfile, fails if out of sync, and never writes to disk).

Why does npm install add ^ before the version?

By default npm saves a caret range ("express": "^4.18.2"), allowing patch and minor updates. To save exact versions instead, run npm install --save-exact or set save-exact=true in .npmrc.

What's the difference between dependencies and devDependencies?

dependencies are required to run the app in production. devDependencies are only needed during development (tests, build tools, linters). When someone installs your published package, they don't get your devDependencies. For apps (not libraries), the distinction mainly matters for npm ci --omit=dev in production deploys.

How do I fix EACCES permission errors with global installs?

Don't use sudo npm install -g. Instead, change the default npm prefix to a user-writable location:

mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH  # Add to ~/.bashrc or ~/.zshrc

My node_modules is huge — what can I do?

First, use npm dedupe to flatten duplicates. Check what's eating space with npx cost-of-modules. Consider switching to pnpm which uses a global content-addressable store and hard links (can save GBs on disk). Also ensure devDependencies are omitted in production with npm ci --omit=dev.

How do I use a private registry (like GitHub Packages or Artifactory)?

Add to .npmrc in the project root:

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

This scopes the private registry to @mycompany packages only. Everything else still resolves from the public npm registry.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools