# Keep dependency updates local before the bot opens a PR

> npm-check-updates and python-check-updates are small scouts for dependency drift, not replacements for CI.

Dependency bots are useful, but I do not want every package manager to become a surprise inbox.
Before a bot opens a branch, I like having a local habit for checking drift, grouping the work, and
deciding what deserves a real CI run.

`npm-check-updates` is good for the JavaScript side of that loop. It looks at `package.json`, shows
newer versions, and can update the manifest when I am ready to do the real work. The important word
is ready. I do not treat dependency updates as a button that magically makes the repo healthier.
They are code changes. They deserve a branch, a lockfile diff, tests, and a quick read of the risky
packages.

`python-check-updates` gives the same shape to Python projects: a fast local check against PyPI
before I decide whether to touch the lockfile. That matters in mixed stacks where the frontend, CLI,
worker, and scripts all drift at different speeds. A small local command makes the drift visible
without turning the first signal into a pull request.

```mermaid
flowchart LR
  A[local checkout] --> B[check manifest drift]
  B --> C[group updates by risk]
  C --> D[read changelogs for runtime packages]
  D --> E[update manifest + lockfile]
  E --> F[run repo checks]
  F --> G[open one reviewable PR]
```

<Principle title="Local signal before automated noise">
  A dependency bot should not be the first time the maintainer sees routine drift. Local checks keep
  the operator close to the repo and make the eventual PR smaller, calmer, and easier to review.
</Principle>

## The loop I want

For a Bun or npm-style project, I usually want the first pass to be read-only:

```bash
npx npm-check-updates
```

Then I split the result into boring updates, runtime-sensitive updates, and package-boundary changes.
UI libraries, bundlers, database clients, auth packages, generated SDK tooling, and test runners do
not get treated like a random patch bump. If the package can change how the app builds, talks to the
network, serializes data, or validates user input, I read more before I touch the lockfile.

When the set is small enough to review:

```bash
npx npm-check-updates -u
bun install
bun test
bun run typecheck
```

For Python projects, the same habit applies. Install the checker, run it locally, then let `uv` own
the environment and lockfile after the update decision is made:

```bash
cargo install python-check-updates
python-check-updates
uv lock
uv run pytest
```

The tool does not replace judgment. It gives the judgment a cleaner starting point.

## How this fits with Renovate

Renovate is still useful. The bot handles schedules, grouping, dashboards, and boring repetition.
The local check handles operator awareness. I want both because they solve different parts of the
same maintenance problem.

The local pass is especially useful before a maintenance window, before cutting a release, or after a
long-running feature branch has been away from main for too long. It lets me answer the practical
question before automation creates work for everyone else: is this a small refresh, or did the
platform move under us?

## What belongs in Lab

This is the kind of thing I want Lab to capture: small tools that remove operational friction. The
same bucket should eventually include zsh setup, Ansible workstation bootstrap, local installs, and
Tailscale routes for exposing development services safely. The common thread is not novelty. It is
developer leverage: less repeated setup, fewer forgotten steps, and a local path that stays close to
how the system is actually built and shipped.
