Global vs Local Packages
Packages can be installed locally (per project) or globally (system-wide). Understanding when to use each is important.
Local Installation (Default)
npm install lodash
- Installed in
./node_modules/ - Added to
package.json - Available only in this project
- Can vary between projects
Global Installation
npm install -g typescript
- Installed in a system directory
- Available everywhere
- Not added to any
package.json - Same version for all projects
Finding Global Install Location
npm root -g
# Example: /usr/local/lib/node_modules
When to Use Each
Use Local Packages
- Libraries used in your code
- Build tools
- Test frameworks
- Project-specific CLIs
npm install express # Library
npm install -D jest # Test framework
npm install -D webpack # Build tool
Use Global Packages
- CLI tools you use across projects
- Tools not specific to any project
- Scaffolding tools
npm install -g create-react-app # Project scaffolding
npm install -g serve # Static file server
npm install -g npm-check-updates # Dependency updater
The Modern Approach: npx
Instead of global installs, use npx:
# Instead of:
npm install -g create-react-app
create-react-app my-app
# Use:
npx create-react-app my-app
Benefits of npx:
- Always uses the latest version
- No global pollution
- Works even if package isn't installed
Common npx Use Cases
# Create projects
npx create-react-app my-app
npx create-next-app my-site
npx create-vite my-project
# Run tools once
npx prettier --write .
npx eslint src/
npx tsc --init
# Try packages
npx cowsay "Hello npm!"
Managing Global Packages
List Global Packages
npm list -g --depth=0
Update Global Packages
npm update -g
# Update specific package
npm update -g typescript
Uninstall Global Packages
npm uninstall -g typescript
Local Binaries in npm Scripts
Local packages with CLI tools are accessible in npm scripts:
{
"devDependencies": {
"typescript": "^5.3.0"
},
"scripts": {
"build": "tsc"
}
}
You don't need ./node_modules/.bin/tsc - npm adds it to the PATH automatically.
Directly Running Local Binaries
# Using npx
npx tsc --version
# Using npm exec
npm exec -- tsc --version
# Direct path
./node_modules/.bin/tsc --version
Practice: Package Installation Comparison
Global Package Issues
Version Conflicts
Different projects may need different versions:
# Project A needs TypeScript 4.x
# Project B needs TypeScript 5.x
# Global install can only have one version!
Solution: Use local installs.
Permission Problems
Global installs may require sudo on Linux/macOS:
# Problematic
sudo npm install -g some-package
# Better: Change npm's default directory
npm config set prefix ~/.npm-global
export PATH=~/.npm-global/bin:$PATH
Reproducibility
Global packages aren't in package.json, so:
- Other developers might not have them
- CI/CD pipelines won't have them
Best Practices
1. Prefer Local Over Global
# Instead of:
npm install -g typescript
tsc
# Do:
npm install -D typescript
npx tsc
2. Use npx for CLI Tools
npx eslint --init
npx prettier --write .
npx tsc --init
3. Document Required Global Tools
If you must use global packages, document them:
## Prerequisites
- Node.js 18+
- npm 9+
- Global: `npm install -g vercel`
4. Use postinstall for Setup
{
"scripts": {
"postinstall": "husky install"
}
}
Summary Table
| Aspect | Local | Global |
|---|---|---|
| Location | ./node_modules/ | System directory |
| In package.json | Yes | No |
| Versioning | Per-project | System-wide |
| Command | npm install pkg | npm install -g pkg |
| Preferred | Yes | Rarely |
Key Takeaways
- Local is preferred for almost everything
- Use npx instead of global installs
- Global for system-wide CLI tools only
- Local binaries work in npm scripts automatically
- Document any required global packages
What's Next?
Let's explore package-lock.json and how it ensures reproducible builds.

