Python packaging has long been a source of frustration for developers. For years, we've juggled multiple tools — pip for installing packages, venv or virtualenv for creating isolated environments, pip-tools for lock files, pyenv for managing Python versions, and Poetry for larger projects. Each tool solves a specific problem, but together they create a fragmented, error-prone workflow.
Enter uv — a fast Python package and project manager built by Astral, the same team behind the popular linter Ruff. After making the switch, I've found myself asking one simple question: Why was I using three different tools when one tool can do most of the work?
What Is uv?
uv is a Rust-powered Python package and project manager that can replace pip, pip-tools, pipx, Poetry, pyenv, twine, virtualenv, and more. Think of it as a unified command-line tool that handles:
- Package installation
- Virtual environment creation and management
- Dependency resolution and lock files
- Python version management
- Script execution
- Tool installation and execution
The easiest way to understand uv is this: instead of reaching for one tool for installing packages, another for virtual environments, another for lock files, and another for managing Python versions, uv brings most of that workflow into a single place.
And it's fast — reportedly 10–100x faster than pip. That's not just a marketing claim; in daily use, the difference is immediately noticeable.
The Old Workflow: A Tale of Too Many Tools
Before uv, my Python workflow looked something like this:
# Create a virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\Activate.ps1
# Install packages
pip install pandas scikit-learn streamlit
pip freeze > requirements.txtFor larger projects, I'd switch to Poetry:
poetry init
poetry add pandas scikit-learn streamlit
poetry run python main.pyThis worked, but it always felt like I was jumping between different tools and different workflows. Sometimes I had a requirements.txt file. Sometimes I had a pyproject.toml file. Sometimes I had a lock file. Sometimes I forgot to activate the virtual environment and installed packages globally by mistake.
None of these tools are bad — they're popular for good reasons. But the workflow wasn't clean, consistent, or efficient.
The New Workflow: One Tool to Rule Them All
With uv, starting a new Python project feels dramatically simpler:
uv init my-project
cd my-project
uv add pandas scikit-learn streamlit
uv run main.pyThat's it. When I run these commands, uv handles most of the setup for me:
- Creates the project structure
- Manages dependencies in
pyproject.toml - Creates a
.venvvirtual environment - Generates a
uv.lockfile for reproducible installs
The best part? I don't have to activate the environment every time. Instead of:
source .venv/bin/activate
python script.pyI can just run:
uv run script.pyuv run checks that the environment is in sync with the lock file and runs the command using the right dependencies. For me, this is the biggest quality-of-life improvement. I spend less time thinking about environments and more time actually building the project.
Why I Love uv
1. A Unified Python Workflow
This is the single biggest reason I switched. Before uv, my workflow was split across different tools — pip for packages, venv or virtualenv for environments, pip freeze for requirements, Poetry for larger projects, and sometimes pyenv for Python versions.
With uv, most of this happens in one place:
uv init
uv add requests
uv add --dev pytest
uv run pytestThis creates a cleaner workflow where I can create the project, add dependencies, manage the environment, generate a lock file, and run commands without constantly switching between tools.
2. Blazing Fast Performance
Speed isn't everything, but it matters when you're creating projects again and again. Installing dependencies with pip can feel slow, especially in fresh environments or CI pipelines.
uv is written in Rust and is designed for speed. In my own workflow, that difference is noticeable — project setup feels much faster, especially for projects with heavier dependencies like transformers, torch, scikit-learn, or other data science and machine learning packages.
Benchmarks consistently show uv performing 10–100x faster than pip. The global cache and parallel installs make a real difference in everyday development.
3. Cleaner Project Setup
With uv, the project flow feels more modern and streamlined:
uv init
uv add fastapi
uv add --dev pytest
uv run pytestDependencies stay inside pyproject.toml, a lock file ensures reproducibility, and the project becomes much easier to share and reproduce on another machine.
Instead of telling someone: "Create a virtual environment, activate it, install the requirements, and make sure the Python version is correct," you can often just say:
uv sync
uv run main.pyThat's much cleaner.
4. Easy Migration Path
Another reason I appreciate uv is that I don't have to change everything at once. If I have an older project that still uses a requirements.txt file, I can use uv without converting the whole project:
uv venv
source .venv/bin/activate
uv pip install -r requirements.txtThis gradual adoption path means I can start by using uv as a faster installer in existing projects, then use uv init, uv add, and uv sync for new projects. Migration doesn't have to be all or nothing.
5. Python Version Management
uv can also install and manage Python versions, replacing parts of a pyenv workflow:
uv python install 3.12
uv python pin 3.12
uv syncInstead of separately managing Python versions, virtual environments, and dependencies, I can keep more of that workflow inside one tool.
6. Tool Execution with uvx
uv also includes uvx, which works like npx for Python tools. You can run Python-based CLI tools in isolated temporary environments without installing them globally — perfect for one-off tasks or trying out new tools.
Installation
Installing uv is straightforward. Open your terminal and run the command for your operating system:
macOS and Linux:
curl -LsSf https://astral.sh/uv/install.sh | shWindows PowerShell:
irm https://astral.sh/uv/install.ps1 | iexYou can also install uv using pip, Homebrew, WinGet, Scoop, Docker, Cargo, and other methods. But for most users, the standalone installer is the simplest option.
Should You Switch to uv?
For new Python projects, I think uv is an easy recommendation. It's fast, modern, and brings project setup, dependency management, virtual environments, lock files, Python versions, and tool execution into one workflow.
The docs also say uv provides a familiar pip-compatible interface, so you can start with uv pip before fully moving to uv init, uv add, and uv sync.
That said, I wouldn't tell everyone to switch immediately:
- For data science beginners,
condais still a good starting point because it's widely used for managing environments and packages in data science workflows. - For vibe coders using AI coding tools,
pip,venv, andrequirements.txtare still worth knowing because many AI models are trained on older Python workflows and may generate instructions that don't work smoothly with uv. - For Python developers, product engineers, and people setting up projects often, I would highly recommend trying uv.
The Bottom Line
My recommendation is simple: keep conda if you're just starting with data science, learn pip because it's still everywhere, but use uv for new Python projects where you want a faster and cleaner developer experience.
uv isn't just a faster pip — it's a fundamental rethink of how Python development workflows should work. It gives you one consistent way to manage Python projects, eliminates the friction of juggling multiple tools, and makes the entire process faster and more enjoyable.
Have you tried uv yet? What's your experience been like? Share your thoughts in the comments below!