Map

uv is fantastic, but its package management UX is a mess

Sources Kevin Renskerspythonuvastralpackage-management ↳ show in map Markdown
title
uv is fantastic, but its package management UX is a mess
author
Kevin Renskers
date
2026-05-21
tags
python, uv, astral, package-management

uv is fantastic, but its package management UX is a mess

By Kevin Renskers · May 21, 2026 · loopwerk.io

Astral's uv is rightfully celebrated for speed and for collapsing the Python toolchain (venv, pip, pyenv, pip-tools, poetry) into one Rust binary. Day-to-day project maintenance — finding outdated packages, updating them, keeping the lockfile honest — is where the experience drops below what Poetry and pnpm already deliver.

No uv outdated

There is no dedicated outdated command. The closest incantation is:

$ uv tree --outdated --depth 1

It dumps the whole dependency tree rather than just the rows that are behind. Compare:

$ pnpm outdated

…which gives a clean filtered table.

Open-ended version constraints by default

uv add pydantic writes this into pyproject.toml:

dependencies = [
    "pydantic>=2.13.4",
]

No upper bound. The next uv lock --upgrade is free to jump pydantic to 3.x, then 4.x, then 100.x. pnpm and Poetry default to ^1.23.4 (caret) or an explicit >=1.23.4,<2.0.0 range, which at least respects SemVer's major-version line.

uv lock --upgrade, not uv update

To update everything:

$ uv lock --upgrade

The author flags two things: (1) "update" or "upgrade" would be a more obvious verb at the top level; (2) the CLI is internally inconsistent — uv add and uv remove are top-level, but there is no uv lock --add or uv lock --remove, so it's unclear why upgrade lives under uv lock.

Per-package upgrades repeat the flag:

$ uv lock --upgrade-package pydantic --upgrade-package httpx --upgrade-package uvicorn

vs.

$ pnpm update pydantic httpx uvicorn

The --bounds escape hatch

A recent preview flag adds opt-in upper bounds:

$ uv add pydantic --bounds major

Produces pydantic>=2.13.4,<3.0.0. Still opt-in, still preview-flagged, doesn't fix what existing projects already have.

Practical dilemma

Today's choices for a uv user:

  1. Hand-edit pyproject.toml after every uv add to add upper bounds.
  2. Accept that uv lock --upgrade can silently introduce major-version breakage.

What would fix it

  • A real uv outdated that filters its output.
  • A top-level uv update [packages...] without flag repetition.
  • Default constraint behavior that respects SemVer boundaries (or at least makes the choice explicit at uv init time).

Conclusion

"the developer experience for maintaining a project is currently a step backward from the tools that came before it"

Until the gaps close, lockfile diffs need careful review.