Astral is good: uv


Like my Astral is good: ruff post, I feel that Python dependency management has also been a nightmare for a decade. My personal journey has been some combination of virtualenv, virtualenv + pyenv, and--most recently--a Frankenstein monster of poetry and pyenv. Poetry promised to fix things, and for a while, it did. But Poetry is slow, bloated, and increasingly frustrating to use in real projects with real devs.

uv fixes this.

What is uv?

uv is a Python package manager written in Rust by the same team behind Ruff. It replaces pip, pipx, poetry, pyenv, and virtualenv with a single (lightning-fast) tool.

# Before uv (Poetry)
poetry install        # 45s
poetry add requests   # 12s
poetry shell         # 2s

# With uv
uv sync              # 1.2s
uv add requests      # 0.3s
uv run python        # instant
The Poetry Problem

Poetry was revolutionary when it launched. Finally, a tool that handled dependency resolution, virtual environments, and publishing in one package. But Poetry suffers from fundamental issues:

Slow dependency resolution

Poetry's resolver is notoriously slow. Installing dependencies for a medium-sized project takes minutes. Adding a single package often triggers a complete dependency graph recalculation.

Virtual environment confusion

Poetry creates virtual environments in obscure locations. I'm still a bit confused why poetry config virtualenvs.in-project is not true by default. Finding where your actual environment lives requires running poetry env info. becomes a treasure hunt.

The uv Solution
Speed

uv resolves and installs dependencies in seconds, not minutes. It uses a state-of-the-art resolver written in Rust that's orders of magnitude faster than Poetry's Python implementation.

Better lock files

uv's lock files are minimal and designed to avoid merge conflicts. They track only what matters, not Poetry's verbose metadata soup.

Transparent environments

uv creates .venv in your project directory by default. Your virtual environment is where you expect it to be. No more hunting through ~/.poetry/bin/poetry or, goodness-forbid: ~/Library/Caches/pypoetry.

Drop-in replacement

uv reads your existing pyproject.toml. Migration from Poetry takes minutes:

# Convert your Poetry project
uv sync
rm poetry.lock  # Optional, but satisfying
The Migration

I migrated three production projects from Poetry to uv last month. Each migration took under 10 minutes:

  1. uv sync to read the existing pyproject.toml
  2. Delete the poetry.lock file
  3. Update CI/CD scripts to use uv sync instead of poetry install

That's it. No configuration changes, no dependency updates, no breaking changes. I cut minutes off of my docker builds with minutes of dev.

The Reality

Speed isn't the only win. uv consolidates the entire Python toolchain. Need to run a script in an isolated environment? uv run. Need to install a CLI tool? uv tool install. Need Python 3.12? uv python install 3.12.

Poetry promised to be the one tool for Python dependency management. uv actually delivers on that promise.

What's the catch?

uv is young. Some Poetry features aren't implemented yet (like publishing to private registries), though the roadmap indicates these are are on the way. The team moves fast and the tool is remarkably stable for something so new.

If you're building internal tools or applications (not publishing packages), uv is a no-brainer upgrade.

The Bottom Line

I've stopped using Poetry for all but publishing to pypi. uv handles everything I need, runs 50x faster, and doesn't make me wait for dependency resolution during development.

Switch to uv. Your future self will thank you when you're not waiting 30 seconds for poetry add to finish.

Back to posts
TwitterUdemyMy Twitter ProfileMy Instagram

Copyright © Kevin Katz 2025

Privacy