Python Packaging in 2025: uv, Poetry, and pip-tools Compared
Compare uv, Poetry, and pip-tools for Python dependency management. Speed benchmarks, lockfile strategies, virtual environments, monorepo support, and...
The Python Packaging Problem
Python's packaging ecosystem has been historically painful. pip does not have a lockfile. virtualenv requires manual management. Dependency resolution can be slow and nondeterministic. In 2025, we finally have good solutions.
A well-structured configuration file is the foundation of reproducible infrastructure.
uv: The Fast New Standard
uv by Astral (the creators of Ruff) is written in Rust and is dramatically faster than any other Python package manager. It is a drop-in replacement for pip, pip-tools, virtualenv, and more.
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Create a new project
uv init my-project
cd my-project
# Project structure created:
# my-project/
# ├── pyproject.toml
# ├── .python-version
# └── src/
# └── my_project/
# └── __init__.py
# pyproject.toml (uv-managed)
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"fastapi>=0.115",
"uvicorn[standard]>=0.32",
"sqlalchemy>=2.0",
"pydantic>=2.9",
]
[project.optional-dependencies]
dev = [
"pytest>=8.3",
"ruff>=0.7",
"mypy>=1.13",
]
[tool.uv]
dev-dependencies = [
"pytest>=8.3",
"ruff>=0.7",
]
# Add dependencies
uv add fastapi uvicorn sqlalchemy pydantic
uv add --dev pytest ruff mypy
# Lock dependencies (creates uv.lock)
uv lock
# Sync environment with lockfile
uv sync
# Run commands in the virtual environment
uv run python app.py
uv run pytest
uv run fastapi dev
# Install a specific Python version
uv python install 3.12
uv python pin 3.12
# Build and publish
uv build
uv publish
uv speed comparison (installing 50 packages):
Get more insights on Tutorials
Join 2,000+ engineers who get our weekly deep-dives. No spam, unsubscribe anytime.
uv sync: 0.8 seconds
pip install: 45 seconds
poetry install: 38 seconds
pip-tools sync: 42 seconds
uv is 50x faster than pip. This matters in CI/CD where every second counts.
Poetry: The Mature Solution
Poetry has been the standard for Python dependency management since 2018. It provides deterministic builds, a lockfile, virtual environment management, and publishing.
# Install Poetry
curl -sSL https://install.python-poetry.org | python3 -
# Create a new project
poetry new my-project
cd my-project
# Or initialize in existing directory
poetry init
# pyproject.toml (Poetry)
[tool.poetry]
name = "my-project"
version = "0.1.0"
description = "My awesome project"
authors = ["Yash Pritwani <[email protected]>"]
[tool.poetry.dependencies]
python = "^3.12"
fastapi = "^0.115"
uvicorn = {version = "^0.32", extras = ["standard"]}
sqlalchemy = "^2.0"
pydantic = "^2.9"
[tool.poetry.group.dev.dependencies]
pytest = "^8.3"
ruff = "^0.7"
mypy = "^1.13"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
# Add dependencies
poetry add fastapi uvicorn sqlalchemy
poetry add --group dev pytest ruff
# Install from lockfile
poetry install
# Run commands
poetry run python app.py
poetry run pytest
# Update dependencies
poetry update
poetry update fastapi # Update specific package
# Export to requirements.txt (for Docker)
poetry export -f requirements.txt --output requirements.txt --without-hashes
# Build and publish
poetry build
poetry publish
Docker Compose brings up your entire stack with a single command.
pip-tools: The Simple Approach
pip-tools is the minimal solution: just pip-compile (generates lockfile) and pip-sync (installs from lockfile). No virtual environment management, no project scaffolding.
# Install pip-tools
pip install pip-tools
# Define requirements
# requirements.in
fastapi>=0.115
uvicorn[standard]>=0.32
sqlalchemy>=2.0
pydantic>=2.9
# requirements-dev.in
-r requirements.in
pytest>=8.3
ruff>=0.7
mypy>=1.13
# Generate lockfile (requirements.txt)
pip-compile requirements.in --output-file requirements.txt
pip-compile requirements-dev.in --output-file requirements-dev.txt
# Install from lockfile
pip-sync requirements.txt
# For development
pip-sync requirements-dev.txt
# Update all
pip-compile --upgrade requirements.in
# Update specific package
pip-compile --upgrade-package fastapi requirements.in
Comparison
| Feature | uv | Poetry | pip-tools |
|---|---|---|---|
| Speed | Blazing fast (Rust) | Slow (Python) | Moderate |
| Lockfile | uv.lock | poetry.lock | requirements.txt |
| Virtual env management | Yes | Yes | No (use venv) |
| Python version management | Yes | No (use pyenv) | No |
| Project scaffolding | Yes (uv init) | Yes (poetry new) | No |
| Dependency groups | Yes | Yes | Multiple .in files |
| Build/publish | Yes | Yes | No |
| PEP 621 compliant | Yes | Partial (own format) | N/A |
| Monorepo support | Yes (workspaces) | No | Manual |
| pip compatible | Yes (drop-in) | No (own resolver) | Yes |
| CI/CD caching | uv.lock hash | poetry.lock hash | requirements.txt hash |
| Docker integration | Excellent | Good (needs export) | Native pip |
| Maturity | New (2024+) | Mature (2018+) | Mature (2016+) |
Docker Integration
uv in Dockerfile (recommended):
FROM python:3.12-slim
# Install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
# Set up project
WORKDIR /app
COPY pyproject.toml uv.lock ./
# Install dependencies (cached layer)
RUN uv sync --frozen --no-dev --no-install-project
# Copy source code
COPY src/ src/
# Install the project
RUN uv sync --frozen --no-dev
CMD ["uv", "run", "uvicorn", "app:main", "--host", "0.0.0.0", "--port", "8000"]
Free Resource
Free Cloud Architecture Checklist
A 47-point checklist covering security, scalability, cost optimization, and disaster recovery for production cloud environments.
Poetry in Dockerfile:
FROM python:3.12-slim
RUN pip install poetry
RUN poetry config virtualenvs.create false
WORKDIR /app
COPY pyproject.toml poetry.lock ./
RUN poetry install --no-dev --no-interaction --no-ansi
COPY . .
CMD ["uvicorn", "app:main", "--host", "0.0.0.0", "--port", "8000"]
pip-tools in Dockerfile:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "app:main", "--host", "0.0.0.0", "--port", "8000"]
Docker Compose defines your entire application stack in a single YAML file.
Our Recommendation
For new projects in 2025: Use uv. It is the fastest, has the best developer experience, manages Python versions, supports workspaces, and is PEP 621 compliant. The Astral team (behind Ruff) ships reliable software.
For existing Poetry projects: Stay with Poetry unless you hit performance issues in CI/CD. Migration to uv is straightforward if needed.
For minimal needs: pip-tools is fine if you only need a lockfile and already manage virtualenvs yourself.
At TechSaaS, we use uv for all new Python projects. The speed difference is transformative in CI/CD — our Docker builds with uv take 3 seconds for dependency installation versus 45 seconds with pip. We also use uv's Python version management to eliminate the need for pyenv on developer machines and CI runners.
Related Service
Cloud Solutions
Let our experts help you build the right technology strategy for your business.
Need help with tutorials?
TechSaaS provides expert consulting and managed services for cloud infrastructure, DevOps, and AI/ML operations.
We Will Build You a Demo Site — For Free
Like it? Pay us. Do not like it? Walk away, zero complaints. You will spend way less than hiring developers or any agency.
No spam. No contracts. Just a free demo.