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 tagUpdating & 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 cinpm 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 --versionDependency 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 installKeep your own version of these notes — editable, searchable, and organised by your stack.
Start free