How to Update Your JavaScript Dependencies
TL;DR
# list your outdated packages / check if a specific package is outdated
npm outdated
yarn outdated [package]
# update / upgrade and save changes to package.json
npm update [package] --save|--save-dev
yarn upgrade [package]
The Practical Guide to Managing Outdated JavaScript Dependencies
Why This Matters
We've all been there, you inherit a codebase where nobody's touched the dependencies in 18 months, and suddenly you're staring at 147 outdated packages and a security audit that looks like a horror movie.
Managing JavaScript dependencies isn't the sexy part of our job, but ignoring it is like skipping oil changes on your car - eventually, you're stranded on the side of the road with a smoking engine and a deadline tomorrow.
Package Versioning: The Basics
JavaScript follows Semantic Versioning with three numbers: MAJOR.MINOR.PATCH
- Major: "We broke stuff" (API changes)
- Minor: "We added stuff" (backward-compatible)
- Patch: "We fixed stuff" (bug fixes)
In your package.json, you'll see these version specifiers:
Symbol | Example | What it means | When to use it |
---|---|---|---|
Exact | 1.2.3 | Exactly this version | Critical dependencies |
Caret (^) | ^1.2.3 | Any 1.x.x version | Most dependencies |
Tilde (~) | ~1.2.3 | Any 1.2.x version | When you're paranoid |
Finding the Outdated Stuff
NPM Commands
# The command you'll run most often
npm outdated
# For global packages
npm outdated -g
Yarn Commands
# Basic outdated check
yarn outdated
# Check specific packages
yarn outdated react react-dom
Better Tools
The built-in commands are fine, but these will save you time:
# Install npm-check globally
npm install -g npm-check
# Run it for interactive updates
npm-check -u
# Or try npm-check-updates
npm install -g npm-check-updates
# Run it to see what's outdated
ncu
# Update package.json directly
ncu -u
Updating Your Dependencies
NPM Approach
# Safe updates within your version constraints
npm update
# Update a specific package
npm update lodash
# Update and save to package.json
npm update --save
# Update dev dependencies
npm update --save-dev
# Update npm itself (do this first)
npm install -g npm@latest
Yarn Approach
# Basic update within constraints
yarn upgrade
# Update specific package
yarn upgrade lodash
# Update to latest versions (ignores constraints)
yarn upgrade --latest
# Interactive mode (my personal favorite)
yarn upgrade-interactive --latest
Security Vulnerabilities
NPM Security
# Run this after your morning coffee
npm audit
# Fix what can be fixed automatically
npm audit fix
# Fix everything possible (might break stuff)
npm audit fix --force
# Only fix production dependencies
npm audit fix --only=prod
Yarn Security
# Basic audit
yarn audit
# Yarn doesn't have audit fix, so this workaround:
npm i --package-lock-only
npm audit fix
yarn import
rm package-lock.json
Real-World Dependency Management
My Team's Approach
-
Weekly Dependency Day: We dedicate Friday afternoons to package updates. It's not exciting, but neither is getting paged at 2 AM for a security vulnerability.
-
Incremental Updates: Don't update everything at once. Start with patch updates, then minor, then tackle major versions separately.
-
Test Everything: Our CI pipeline runs all tests against updated dependencies before we merge. Trust me, this has saved us countless headaches.
-
Lockfiles Are Sacred: Commit your package-lock.json or yarn.lock. These files ensure everyone on the team gets exactly the same dependency tree.
-
Clean Installs in CI/CD:
# NPM clean install
npm ci
# Yarn clean install
yarn install --frozen-lockfile
Automation That Works
Add these to your package.json scripts:
"scripts": {
"deps:outdated": "npm outdated",
"deps:update": "npm update --save",
"deps:security": "npm audit",
"deps:security:fix": "npm audit fix"
}
Consider setting up Dependabot or Renovate to automate PR creation for outdated packages. They'll create separate PRs for each dependency, making reviews manageable.
Troubleshooting the Inevitable Problems
When updates go sideways (and they will):
-
Read the Changelog: Most issues can be avoided by actually reading what changed.
-
One at a Time: If you're updating a critical package with breaking changes, do it in isolation.
-
Bisect Method: When something breaks after updates, use
git bisect
to find which package caused it. -
Peer Dependencies: Watch for peer dependency warnings. They're easy to miss but cause subtle bugs.
-
Last Resort: Sometimes
rm -rf node_modules && npm install
really is the answer. We've all been there.
Conclusion
Dependency management isn't glamorous, but it's part of being a professional. Build it into your workflow now, or pay the technical debt with interest later.
Remember: your future self (or the poor dev who inherits your codebase) will either curse or thank you based on how you handle this stuff today.