Updating Packages
Dependencies are not "install once and forget". They ship bug fixes, performance gains, and — critically — security patches. But updating carelessly breaks builds. The skill is knowing what changed, how far an update reaches, and which command to use for safe (in-range) updates versus deliberate (cross-major) upgrades.
See what is outdated
npm outdated
Package Current Wanted Latest Location express 4.18.2 4.19.2 4.19.2 my-app lodash 4.17.20 4.17.21 4.17.21 my-app typescript 5.3.3 5.3.3 5.4.5 my-app
Column | Meaning |
|---|---|
| What is installed right now (from the lockfile) |
| The newest version your |
| The newest version published, ignoring your range |
Safe, in-range updates
npm update moves each package to the newest version its package.json range permits, and rewrites the lockfile. It never crosses a boundary your range forbids — so with ^ ranges it will take minors and patches but never a new major:
npm update # update everything within allowed ranges npm update express # update just one package, in-range npm update --save # also bump the ^ranges in package.json to match
Deliberate major upgrades
Crossing a major is a decision, not a routine. Install the new major explicitly — npm updates the range for you — then read the changelog and run your tests:
npm install express@5 # jump to the latest 5.x; updates the ^range npm install express@latest # jump to whatever "latest" points to npm install typescript@5.4.5 # pin an exact new version
Security-driven updates
npm audit cross-references your tree against the advisory database and reports known vulnerabilities. npm audit fix applies the in-range updates that resolve them:
npm audit # report vulnerabilities, severity, and paths npm audit fix # auto-update vulnerable deps within ranges npm audit fix --force # allow breaking (cross-major) fixes — review after!
A safe update workflow
Branch first — never update on
main. A failed upgrade should be a discarded branch, not a revert.Run
npm outdatedto see the landscape; separate in-range bumps from major jumps.Do in-range updates with
npm update, commit, run tests.Do majors one at a time —
npm install pkg@latest, read its migration guide, fix, test, commit. Bundling majors makes failures impossible to bisect.Automate the noise — tools like Dependabot or Renovate open per-package PRs with changelogs and run CI, so routine bumps review themselves.