/commands/pnpm/pnpm-update-latest
pnpm update --latest: update dependencies to the latest versions with pnpm
- tool
- pnpm
- versions
- pnpm 8+, pnpm 9
- os
- any
pnpm update (alias pnpm up) updates dependencies to the newest versions allowed by the ranges in package.json; pnpm update --latest (-L) ignores those ranges, installs the version tagged latest on the registry and rewrites package.json. Run pnpm outdated first to see what would change, and name packages (pnpm up -L lodash) to update only those.
Outdated, update, update --latest
echo '{ "name": "app", "version": "1.0.0", "private": true }' > package.json
P="npx --yes pnpm@9"
$P add --silent is-odd@2.0.0 lodash@4.17.20
$P outdated
echo "--- pnpm update"
$P update --silent && cat package.json
echo
echo "--- pnpm update --latest"
$P update --latest --silent && cat package.jsonOutput
┌─────────┬─────────┬────────┐
│ Package │ Current │ Latest │
├─────────┼─────────┼────────┤
│ lodash │ 4.17.20 │ 4.18.1 │
├─────────┼─────────┼────────┤
│ is-odd │ 2.0.0 │ 3.0.1 │
└─────────┴─────────┴────────┘
--- pnpm update
{"name":"app","version":"1.0.0","private":true,"dependencies":{"is-odd":"2.0.0","lodash":"4.17.20"}}
--- pnpm update --latest
{"name":"app","version":"1.0.0","private":true,"dependencies":{"is-odd":"3.0.1","lodash":"4.18.1"}}Because the versions were added exactly (pnpm add pkg@x.y.z saves the version as written), plain pnpm update has no room to move and leaves package.json alone. pnpm outdated shows the installed and latest versions and exits with code 1 when something is outdated. --latest then moves both packages to their latest release, including is-odd's new major version. The example runs pnpm through npx pnpm@9; with pnpm installed, drop the npx --yes part.
Variants
| Command | What it does |
|---|---|
| pnpm outdated | Show packages with a newer version (exit code 1 if any) |
| pnpm update | Update all dependencies within their package.json ranges |
| pnpm update lodash | Update one package within its range |
| pnpm update --latest | Update everything to latest and rewrite package.json |
| pnpm update -L react react-dom | Move specific packages to latest together |
| pnpm update '@babel/*' | Update every package matching a pattern |
| pnpm update -i | Interactive: choose which outdated packages to update |
| pnpm update -r --latest | Every package of a workspace |
| pnpm update --dev / --prod | Only devDependencies or only dependencies |
| pnpm update --depth Infinity | Also refresh transitive dependencies to the newest allowed versions |
Pitfalls
- Major versions break things.
--latestcrosses major versions without asking. Preferpnpm update -i --latestto pick packages, and read release notes for each major upgrade. - Pinned ranges stay pinned. An exact version (
"2.0.0") or a tilde range limits what plainpnpm updatecan do; that is by design. - Overrides. Versions forced by
pnpm.overridesinpackage.jsonwin over whatupdatewould pick; adjust the override when you want a different version. - Lockfile. Commit
pnpm-lock.yamlwithpackage.json; otherwise CI fails with ERR_PNPM_OUTDATED_LOCKFILE.
How to confirm it worked
Run pnpm outdated again: no output and exit code 0 mean everything is current. pnpm list shows installed versions, and git diff package.json pnpm-lock.yaml shows what changed. In a workspace, pnpm -r outdated checks every package.
FAQ
What is the difference between pnpm update and pnpm update --latest?
pnpm update stays inside the ranges written in package.json, so ^2.0.0 never becomes 3.x. pnpm update --latest ignores the ranges, installs the version tagged latest and rewrites package.json.
How do I update packages in every workspace package?
Add --recursive (-r): pnpm update -r --latest updates all packages of the workspace. Combine it with --filter to limit the update to some packages.
Why does CI fail after I updated locally?
pnpm update changes pnpm-lock.yaml. If you commit package.json but not the lockfile, pnpm install --frozen-lockfile in CI fails with ERR_PNPM_OUTDATED_LOCKFILE. Commit both files together.