# Dependency updates should arrive as a reviewable loop

> The older Medium note where grouped updates, dashboards, and real checks beat a noisy stream of tiny PRs.

An old but still useful note: dependency updates are not hard because a package changed. They are hard because the work arrives as noise. One package, one PR, one review, repeated across enough repos, becomes a maintenance tax.

## The point

The argument was simple: group the updates, keep a dependency dashboard, and make the repo's own checks decide whether the update lands. The tool matters less than the loop.

Dependency management is a delivery problem disguised as package maintenance. The question is not "which bot is better?" The question is whether the team can accept routine change without turning every update into context switching, review fatigue, or silent risk.

Grouped updates work when the verification loop is real. CI has to catch the break. Tests have to cover behavior that matters. The branch has to be readable enough that a maintainer can understand the blast radius. Without that, automation only moves uncertainty around.

```mermaid
flowchart LR
  A[scheduled update window] --> B[group related deps]
  B --> C[run repo checks]
  C -->|fail| D[inspect changelog + patch]
  D --> C
  C -->|pass| E[review one coherent PR]
```

<Principle title="Automate the arrival, not the judgment">
  The bot can open the branch. The repo checks and the maintainer still decide whether the change is
  safe enough to merge.
</Principle>

## What aged well

- Maintenance should be scheduled, not remembered.
- One reviewable update branch beats a queue of tiny drive-by PRs.
- Automation is useful only when the verification gate is real.
- Dashboards are useful when they show pending work instead of spraying every maintainer with noise.
- The update policy belongs in the repo, close to CI, lockfiles, generated clients, and release notes.

## What I would add now

Today I would add stricter grouping rules, lockfile normalization, and a no-hollow-tests check before calling the branch done.

I would also treat dependency refresh as an engineering hygiene window, not a background chore. Run the app, check the generated artifacts, read the changelog where the package touches runtime behavior, and delete old compatibility code when the new contract is the one you are keeping.

For libraries, I would also check the package surface after the update: ESM/CJS entry points,
exports maps, peer dependency ranges, and generated type output. A dependency PR that passes unit
tests can still break consumers if the package boundary shifted.

The goal is boring forward motion: fewer stale packages, fewer surprise upgrades, and fewer PRs that ask humans to review noise.
