(Note: I work on uv.)
Much of this is useful feedback, even if phrased in a clickbait style. Some thoughts:
- Re: `pnpm outdated`: this is something that hasn't come up very much, even though it seems reasonable to me. I suspect this comes down to cultural differences between Python and JavaScript -- I can't think of a time when I've cared about whether my Python dependencies were outdated, so long as they weren't vulnerable or broken. By contrast, it appears to be somewhat common in the JavaScript ecosystem to upgrade opportunistically. I don't think this is bad per se, but seems to me like a good demonstration of discontinuous intuitions around what's valuable to surface in a CLI between very large programming communities.
- As Armin notes[1], uv's upper bound behavior is intentional (and is a functional necessity of how Python resolution works at large). This is a tradeoff Python makes versus other languages, but I frankly think it's a good one: I like having one copy of each dependency in my tree, and knowing that _all_ of my interdependent requirements resolve to it.
- `uv lock --upgrade` is written like that because it upgrades the lockfile, not the user's own requirements. By contrast, `pnpm update` appears to update the user's own requirements (in package.json). I can see why this is confusing, but I think it's strictly more precise to place under `uv lock`; otherwise, we'd have users with competing intuitions confused about why `uv upgrade` doesn't do their idea of what an upgrade is. Still, it's certainly something we could surface more cleanly, and there's been clear user demand for a uv subcommand that also upgrades the requirements directly.
Agree with you on outdated and upper bounds. However, if users are complaining about the interface being difficult, there is probably something there.
Yes, it makes sense that `uv lock` commands only work the lock file, but users have real needs to upgrade direct and transitive dependencies. For transitive dependencies `uv lock --upgrade-package` works, even if a bit wordy. For direct dependencies, `uv lock --upgrade-package` also works, but doesn't touch `pyproject.toml`, which is much more developer visible. As `uv.lock` package versions get ahead of `pyproject.toml`, `pyproject.toml` becomes a less dependable guide to the surface area of dependencies. A friendly `uv upgrade` command would be nice.
The biggest uv ux footgun I have seen by far is `uv pip`. I have seen a lot of projects use uv correctly with pyproject.toml/uv.lock for development, but then use `uv pip install -r pyproject.toml`, which bypasses uv.lock, in their deployment Dockerfiles and ci tooling. Yes, coding agents are to blame for recommending bad `uv pip` patterns because they have so much `pip` in their training sets, but uv should provide some affordances to protect the user.
Sorry for the rant, uv is a great tool, that I think[0] should be used more! Thank you for your contributions to the ecosystem.
[0] https://aleyan.com/blog/2026-why-arent-we-uv-yet
Author of the article here. Sorry it comes across as “clickbait style” when actually it’s simply Dutch bluntness and honesty
poetry update also updates the lockfile. I really think the way the uv cli is organized makes it quite annoying to work with. It’s designed for correctness, for machines, not for user-friendliness.
Not having used uv but being on the Cargo team for Rust, I wish `cargo update` was `cargo lock update` because it is making our life more difficult to add a version requirement update command/mode inside of Cargo. The effort has been stalled for years.
- Our compatibility guarantees mean we can't fundamentally change `cargo update`
- Using the third-party package name of `cargo upgrade` would be confusing in the distinction between the two
- We have to be very careful adding the mode to the existing command
> the effort has been stalled for years
All because of some cargo-culted command!
Could `update` be deprecated in favor of an alias like`lock-update`?
It's not clickbait style.
Isn't designing for machines "the way" these days?
(Ducks...)
fwiw `uv upgrade` is on the roadmap — we just haven't done it yet because it's hard to build a great experience for it (there are far more nuances than people expect) and we're a small team with a lot of priorities.
Coming to uv from pip, I fall back to
when I need that information.> `pnpm outdated`: this is something that hasn't come up very much, even though it seems reasonable to me.
One use for it is to see what would be updated by running "uv sync --update" or "uv lock --update". Although that might be better served by having a confirmation prompt for those commands.
That’s what the --dry-run argument is for.
That confirmation prompt would then lead to surprises in CI pipelines.
Well, I think the ideal would be to default to prompting, but have a "--yes" or "--non-interactive" option to turn it off in CI and similar, but that might be problematic for backwards compatibility now, but an "--interactive" or "--prompt" flag now would be better than nothing. Especially, if you can configure that in ~/.config/uv/uv.toml
[dead]