HomeFeaturesPricingDocumentationContactDOWNLOAD

How to decide which dependency updates to merge

Decide whether to merge a dependency update using security urgency, blast radius, lockfile changes, release timing, and evidence from your application.

Dependabot and Renovate are good at answering one question: is a newer version available?

That is not the question blocking the merge button.

The question is whether this application should take this update, in this batch, before this release, with the evidence currently available. A green dependency PR can still be a bad Tuesday afternoon.

I use a small policy instead of deciding from scratch every time.

Triage the reason before the version number

Put each update into one of four queues.

Security fix with relevant exposure

Confirm the advisory applies to the version, runtime, and feature you use. If it does, update quickly and follow the incident path your risk requires. “Dev dependency” is not an automatic dismissal if the vulnerable code runs during a build or handles untrusted files.

Routine patch or minor update

Batch low-risk maintenance on a predictable day. Read the changelog, look at the lockfile movement, run the standard release checks, and keep the batch small enough to diagnose.

Major or platform update

Treat it as project work. Read the migration guide, list the affected boundaries, budget time for code changes, and give it its own branch or pull request.

Update with no clear value

Leave it open, defer it with a reason, or remove the package. “A new number exists” is not a product requirement.

GitHub now supports schedules, cooldowns, and grouped version updates in Dependabot configuration. Use those controls to make the queue match your review capacity instead of accepting a permanent wall of bot PRs.

Read the lockfile as part of the diff

A manifest line might show one direct package moving from 4.2.0 to 4.2.1. The lockfile can show dozens of transitive packages changing underneath it.

I check:

  • Did the expected package and only its dependency tree move?
  • Did a package switch registry, source URL, or integrity value?
  • Did the update introduce an install script or optional native package?
  • Did several copies collapse to one version, or one copy split into several?
  • Did a package manager or lockfile format change at the same time?

A large diff is not automatically dangerous. It is harder to attribute. If the update fails, the lockfile tells you how many suspects entered the room.

Use the package manager’s frozen or immutable install mode in CI. The lockfile is what makes an install repeatable. An exact version in package.json can narrow future resolution, but it does not replace a committed lockfile or a clean install check.

Batch by blast radius, not convenience

Ten lint-plugin updates can reasonably travel together. A framework runtime, ORM, authentication library, and payment SDK should not share one “maintenance” pull request just because a bot opened them on Monday.

Useful groups include:

  • Related packages that must stay version-aligned
  • Development-only tooling with the same verification path
  • Type packages paired with their runtime package
  • Low-risk leaf utilities

Bad groups combine unrelated production boundaries. If checkout breaks after a 40-package batch, a green unit-test suite does not tell you which dependency changed the behavior.

My rule is simple: group updates when they share both an owner and a proof plan.

Write the proof plan before upgrading

“CI passes” is a result, not a plan. Before changing the lockfile, name the behavior that would prove the update safe.

For example:

Dependency area Evidence I want
UI framework Production build, hydration check, primary routes, browser console
Database or ORM Migration diff, representative reads and writes, rollback path
Authentication Sign-in, sign-out, expiration, protected route, role boundary
Payment SDK Test checkout, failure, webhook verification, idempotent replay
Build tooling Clean checkout, production bundle, source maps, deployment preview

Run the old version once if the test is new. A test that fails before the update cannot tell you anything about the update.

For a major upgrade, capture the expected warnings and generated-file changes too. Otherwise a noisy “successful” build can hide the one deprecation that matters next month.

Pay attention to transitive changes

You usually did not choose the package that breaks the build. It arrived underneath something you did choose.

Package-manager inspection commands help:

pnpm why package-name
pnpm list package-name --depth Infinity

When a transitive package causes trouble, first identify the direct dependency that owns the path. Avoid dropping a permanent override into the manifest without an exit condition. If an override is necessary, record why it exists, the upstream issue, and what version lets you remove it.

This is also why I keep update pull requests focused. Bisecting three deliberate direct updates is manageable. Bisecting a quarter’s worth of unattended lockfile churn is not.

Make stale dependencies visible

The dangerous package is not always the one with an alert. It may be the package nobody remembers installing.

Once a quarter, ask:

  • Is it imported or used by a script?
  • Does the platform now provide the same capability?
  • Is the maintainer still releasing and responding to security reports?
  • Could a small local function replace it without creating a maintenance trap?
  • Who owns the decision when it needs a major upgrade?

Removing one dependency deletes its future updates, advisories, transitive graph, and review work. That can be a better maintenance result than getting every badge back to green.

A cadence that stays boring

I prefer three lanes:

  1. Relevant security fixes: triage when they arrive.
  2. Routine maintenance: a small weekly or monthly batch with a named owner.
  3. Major upgrades: planned work with explicit acceptance tests.

Close or defer updates with a reason so the queue remains useful. Revisit deferrals on a date, not “later.”

SiteCMD’s dependency update workflow keeps available versions, project context, and verification work together. Whatever tool opens the pull request, run the result through the same pre-launch verification checklist as any other production change.

A dependency PR is still a release. The bot did the typing, not the deciding.