npm
06 / 08

Managing Dependencies & Scripts

npm: Managing Dependencies & Scripts

Installing Packages

# Install all dependencies
npm install
npm ci                          # CI — strict, uses lock file exactly

# Add a dependency
npm install express             # adds to "dependencies"
npm install typescript --save-dev   # adds to "devDependencies"
npm install -D vitest           # shorthand for --save-dev

# Install specific version or tag
npm install react@18.2.0
npm install react@latest
npm install react@beta

# Install without saving to package.json
npm install --no-save some-tool

# Install globally (CLI tools)
npm install -g vercel
npm install -g typescript

# Install from GitHub
npm install github:expressjs/express
npm install expressjs/express#v5.0.0   # from specific tag

Updating & Removing

# View outdated packages
npm outdated

# Update packages (respects semver ranges in package.json)
npm update                      # all packages
npm update express              # specific package

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

# Use npm-check-updates to bump package.json ranges
npx npm-check-updates           # show what would change
npx npm-check-updates -u        # update package.json
npm install                     # install updated versions

# Remove package
npm uninstall lodash
npm uninstall -g old-cli-tool

# Clean install (delete node_modules and reinstall)
rm -rf node_modules && npm ci

npm Scripts

Scripts in package.json run via npm run <name>. Special names run without the "run" keyword: npm start, npm test, npm build. Pre/post hooks run automatically.

{
  "scripts": {
    "build": "tsc -p tsconfig.json",
    "prebuild": "rm -rf dist",
    "postbuild": "node scripts/copy-assets.js",

    "start": "node dist/server.js",
    "dev": "tsx watch src/server.ts",

    "test": "vitest",
    "test:watch": "vitest --watch",
    "test:coverage": "vitest --coverage",

    "lint": "eslint src --ext .ts,.tsx",
    "lint:fix": "eslint src --ext .ts,.tsx --fix",
    "format": "prettier --write src",

    "typecheck": "tsc --noEmit",

    "check": "npm run typecheck && npm run lint && npm run test",

    "db:generate": "drizzle-kit generate",
    "db:migrate": "tsx src/db/migrate.ts",

    "release": "npm run check && npm run build && npm publish"
  }
}
# Run scripts
npm run build
npm run test:coverage
npm test          # shorthand for npm run test
npm start         # shorthand for npm run start

# Pass args to script after --
npm test -- --reporter verbose
npm run build -- --watch

# Run multiple scripts
npm run lint && npm run test     # sequential
npm run lint & npm run test      # parallel (Unix)

# Use npm-run-all for cross-platform parallel/sequential
npm install -D npm-run-all
# "check": "run-p lint typecheck"          (parallel)
# "build": "run-s clean compile copy"       (sequential)

npx — Run Without Installing

# Run a CLI tool without globally installing it
npx create-next-app@latest my-app
npx prisma migrate dev
npx tsx scripts/seed.ts

# Force fresh download (don't use cached)
npx --yes create-react-app my-app

# Run a specific version
npx typescript@5.3.0 --version

Dependency Types

  • dependencies: required at runtime — shipped in production bundle

  • devDependencies: build tools, test frameworks, linters — not included in production

  • peerDependencies: tells consumers what version of a shared dep is expected (e.g., React for a UI library). Consumers must install it themselves.

  • optionalDependencies: install fails gracefully if this package can't install (e.g., platform-specific native modules)

  • overrides: force a specific version of a transitive dependency (npm v8+)

{
  "overrides": {
    "semver": "^7.5.4",
    "postcss": {
      "postcss-loader": "^7.0.0"
    }
  }
}

Local Package Linking

# Link a local package for development
cd my-library
npm link

cd my-app
npm link my-library    # Now node_modules/my-library → your local code

# Unlink
npm unlink my-library

# Alternative: file: protocol in package.json (simpler, works with lock file)
# "my-library": "file:../my-library"
npm install

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free