Dependabot Is Not a Maintenance Strategy

#automated dependency updates

Founder & Lead Developer

Expert in software development and legacy code optimization

LinkedIn

Most teams that turn on Dependabot or Renovate treat it as the finish line, not the start of one. The tool opens pull requests when a new package version is available, and the backlog of outdated dependencies looks solved. A few weeks later the same teams have forty open pull requests, nobody has merged in a while, and the automated dependency updates that were supposed to keep the codebase current are adding a maintenance problem of their own: a long list of unreviewed changes nobody has time for.

This is not a flaw in the tools. Dependabot and Renovate do exactly what they are built to do: watch package manifests, notice new releases, and open a pull request. What they do not do is test the change against your actual application, judge whether a version bump is safe, or merge anything. That part was always going to require a person, and a lot of teams adopt the tooling without planning for who that person is or when they will do the work.

What Dependabot and Renovate actually do well

Both tools solve the same problem: someone has to notice that a package shipped a new version. Before automated dependency updates existed, that meant a developer periodically running npm outdated or composer outdated and comparing version numbers by hand, usually not often enough. Dependabot, built into GitHub, and Renovate, which runs as a bot with more configuration options, both watch your manifest files and open a pull request the moment a new version is published.

Renovate tends to give you more control over how updates get grouped and scheduled, which starts to matter once a project has more than a handful of dependencies. Dependabot is simpler to turn on and sits tightly integrated with GitHub's own security advisories, which makes it a reasonable default for a smaller codebase. Neither tool is better in some absolute sense. The dependabot vs renovate choice usually comes down to how much configuration a team is willing to maintain against how much control they want over grouping and timing.

What both get right is the noticing. A security patch for a package you depend on ships, and within a day you have a pull request flagging it. That is a real improvement over nobody noticing for six months, which was ordinary practice on a lot of codebases before either tool existed.

Where the queue starts to build

The trouble shows up at the next step. A pull request from Dependabot or Renovate sits in GitHub looking exactly like one a developer would open by hand, but nobody wrote it, and nobody is automatically accountable for checking it. If your CI pipeline runs a full test suite, a passing check gives you some confidence. If it does not, or if the suite only covers part of the application, that green checkmark means less than it looks like.

Most teams start with good intentions. The first few automated pull requests get reviewed and merged quickly. Then a sprint gets busy, three open pull requests become fifteen, and reviewing fifteen version bumps feels like a bigger job than reviewing one, so it gets pushed to next week. Next week has its own fifteen. A few months in, the repository has a wall of open pull requests nobody wants to touch, because merging them out of order risks pulling in a dependency on top of another one that has not been tested yet, and the pile has become its own source of risk.

At that point, automated dependency updates have made the problem worse in a specific way. Before the tooling existed, an old package quietly sat there, outdated but stable. Now there is a stack of half reviewed changes, any one of which could introduce a breaking change, and closing the gap means working through them in the right order instead of just picking the most important one.

The parts a tool cannot do for you

A bot can tell you that a package moved from version 3.2 to version 4.0. It cannot tell you whether that jump changed a function signature your code calls, deprecated a default your application relies on, or fixed a bug your code was accidentally depending on. Reading a changelog and deciding whether a major version bump is safe to merge is judgment work, and it requires knowing the application, not just the package.

The same goes for prioritization. A security patch for an authentication library and a routine minor version bump for a formatting utility can both show up as pull requests that look much the same in a GitHub notification list. Someone has to look at each one and decide which matters this week and which can wait for the regular cycle. GitHub's security advisories flag severity reasonably well, but severity alone does not tell you how a package is actually used in your application, and only someone familiar with the codebase can weigh the two together.

Then there is the actual testing. Automated test suites catch a meaningful share of regressions, but most applications do not have coverage deep enough to catch everything a dependency update might break, especially edge cases in how the application calls into a library. A person still needs to look at what changed and decide whether it is worth a manual check before anything ships.

What a working cycle looks like instead

The fix is not to turn off Dependabot or Renovate. It is to treat the pull requests they open as input to a process, rather than the process itself. A monthly cycle works for most applications that are not handling anything unusually sensitive: a set day each month where someone goes through every open dependency pull request, groups the routine ones, flags anything that looks like a breaking change, and merges what is safe. Security patches get pulled out of that cycle and handled on a faster clock of their own, usually within a day or two of the advisory going public rather than waiting for the monthly pass.

This is close to the approach we described when covering what a software maintenance retainer should include: a fixed cadence, a defined testing step, and a separate faster track for anything security related. Automated dependency updates slot into that cycle as the input, not a replacement for it. The tool tells you what changed. The cycle decides what to do about it.

If your repository already has the pile of unreviewed pull requests this post describes, the fastest way out is usually not trying to merge everything at once. Start with security patches, then work backward through the oldest routine updates, since those are the ones most likely to already have a newer version superseding them. A clean queue, kept clean by a regular review instead of a bot running unsupervised, is the actual goal. We have also written about why dependency updates get postponed in the first place, which is worth a look if the pile in your repository looks less like a recent backlog and more like something that has been building for a year.

Who should own this

On a small team, this usually falls to whoever already owns deployments, with a calendar reminder so the monthly pass actually happens instead of getting skipped during a busy sprint. On a larger team, it is worth naming someone specifically, because "whoever has time" tends to mean nobody does. If your team does not have the capacity to own this consistently, it fits naturally into an ongoing code quality consulting engagement, where someone outside the sprint cycle is responsible for keeping the dependency queue from growing unchecked.

Either way, the tool has already done its job the moment it opens a pull request. What happens after that is still on you. If you want a second opinion on how your current dependency queue looks, or want help setting up a cycle that actually keeps it empty, write to us at hello@wolf-tech.io or have a look at wolf-tech.io.