Skip to content

How do uv and Poetry compare?

Poetry and uv both manage Python projects through pyproject.toml, create lockfiles, and handle virtual environments. Poetry has been the default recommendation for years; uv, built by Astral, arrived in 2024 with broader scope and faster dependency resolution. They differ in how.

Scope

Poetry handles dependency management, virtual environments, building, and publishing. Everything else it delegates. A different Python version requires pyenv. Running a CLI tool without installing it globally requires pipx.

uv covers all of that plus Python version management, CLI tool execution (via uvx), and pip-compatible package installation. One binary replaces pyenv, pip, pip-tools, pipx, virtualenv, and Poetry itself. uv takes on more surface area; Poetry stays narrow.

Speed

uv resolves and installs dependencies 10-100x faster than Poetry. On a project with a few dozen dependencies, uv sync finishes in under a second; poetry install takes 10-30 seconds. On large projects with hundreds of transitive dependencies, Poetry’s resolver can take minutes. uv gets this speed from aggressive caching, an optimized resolver, and parallel downloads.

CI pipelines amplify this difference. A GitHub Actions job using uv finishes noticeably faster than the same job using Poetry, and the savings compound across matrix builds and frequent pushes.

Standards Alignment

uv uses PEP 621 metadata and PEP 508 dependency specifiers exclusively. Any PEP 621-compliant tool (hatch, flit, pdm) can read a uv project’s pyproject.toml without modification. The lockfile format is uv-specific, like Poetry’s poetry.lock.

Poetry predates several of these standards and originally used its own metadata format under [tool.poetry]. Poetry 2.0 (January 2025) added PEP 621 support, but many existing projects still use the non-standard format. Poetry’s extras and source declarations also differ from PEP 508 specifiers, so a Poetry project using [tool.poetry.dependencies] requires conversion before other tools can consume it.

Lockfiles

Both tools generate lockfiles for reproducible installs. Poetry writes poetry.lock; uv writes uv.lock. Each pins every transitive dependency to an exact version and records hashes.

A single uv.lock captures resolution for Linux, macOS, and Windows. Poetry’s lockfile is also designed to be cross-platform (environment markers are recorded but not evaluated during resolution), though hash coverage may be incomplete for platforms other than the one where poetry lock ran.

Virtual Environment Management

Poetry creates virtual environments in a centralized cache directory (~/.cache/pypoetry/virtualenvs/ on Linux). This keeps the workspace clean but makes the environment harder to find. Poetry can be configured to use an in-project .venv instead.

uv creates a .venv inside the project by default, matching the convention most editors expect. uv run executes commands within the environment automatically. Poetry offers poetry run for the same purpose; for shell activation, Poetry 2.0 replaced poetry shell with poetry env activate.

Python Version Management

Poetry does not manage Python interpreters. It uses whichever Python is on the system and delegates version management to pyenv.

uv installs and manages Python versions directly. uv python install 3.13 downloads a prebuilt binary in seconds. A .python-version file pins the interpreter, and uv run picks it up automatically. No separate version manager, no compilation step.

Dependency Groups

Poetry introduced dependency groups ([tool.poetry.group.dev.dependencies], [tool.poetry.group.test.dependencies]) before any standard existed for them, letting teams separate development, testing, and documentation dependencies.

uv supports PEP 735 dependency groups ([dependency-groups]) and optional dependencies ([project.optional-dependencies]). PEP 735 is a Python standard, so groups defined this way work across any tool that supports it.

Publishing

Poetry has a built-in poetry publish command with support for multiple repositories, token authentication, and certificate configuration.

uv provides uv publish and uv build. For publishing to PyPI from CI, trusted publishing with GitHub Actions is the recommended approach regardless of tool. See the publishing tutorial for a walkthrough.

Plugin Ecosystem

Poetry supports plugins. The poetry-plugin-export plugin (required for poetry export) and community plugins for dynamic versioning, Docker integration, and monorepo support give Poetry extensibility that uv lacks. Teams with custom Poetry plugins should check whether uv covers their use case before migrating.

uv has no plugin system. Features ship in the binary or not at all.

When to Choose Each

uv is the stronger default for new projects. It resolves faster, manages Python versions without a separate tool, and produces a pyproject.toml that any PEP 621-compliant build backend can read.

Poetry remains a reasonable choice when a project already depends on it and migration cost is high, or when the project relies on Poetry plugins with no uv equivalent.

Teams ready to switch can follow the handbook’s step-by-step guide: How to migrate from Poetry to uv.

Learn More

Last updated on

Please submit corrections and feedback...