What Sets UV Apart
Why UV? With one tool, you get uv python for managing versions and uv add for installing packages—faster and simpler than juggling pip, pyenv, and Poetry.
Here’s how it delivers on both:
- Integration: Replaces pip, virtualenv, pyenv, pipx, and Poetry—simplifying workflows.
- Performance: Built in Rust for fast, efficient installs and resolution.
Below is a quick look at the tools UV consolidates into one streamlined interface:
UV Functionality | Replaces Tool(s) |
---|---|
Dependency management | pip, pip-tools, Poetry |
Virtual environment creation | virtualenv, venv, , Poetry |
CLI tool execution | pipx |
Python version management | pyenv |
Project management | Poetry |
In this article, you’ll learn how to use UV for managing Python environments, dependencies, and tools—all within the context of real data science workflows.
For organizing your project layout, this guide is a helpful complement.
Installing Python with UV
In a typical workflow without UV, you’d use pyenv
to install and manage Python versions, then venv
and pip
to create and manage a virtual environment and dependencies.
For example, you might start a project using Python 3.8 and later decide to upgrade it to Python 3.11. This means switching the Python version with pyenv
, then manually recreating the virtual environment and reinstalling dependencies using pip
.
# Initial project setup with Python 3.8.16
pyenv install 3.8.16
pyenv local 3.8.16
python3 -m venv .venv
source .venv/bin/activate
pip install pandas matplotlib
# Deactivate and remove the current environment
deactivate
rm -rf .venv
# Recreate virtual environment using Python 3.11.2
pyenv install 3.11.2
pyenv local 3.11.2
python3 -m venv .venv
source .venv/bin/activate
pip install pandas matplotlib
With UV, all of this is unified in a single interface. You can switch Python versions and install dependencies using one tool—no need to recreate the virtual environment or reinstall dependencies.
# Start with Python 3.8.16
uv python install 3.8.16
uv python pin 3.8.16
uv add pandas matplotlib
# Upgrade to Python 3.11.2
uv python install 3.11.2
uv python pin 3.11.2
Managing Dependencies for Single-File Scripts
Sometimes, you just want to run a script without installing anything globally—like when exploring data with matplotlib or seaborn for a quick one-off task.
UV makes this effortless by allowing you to declare dependencies inline and automatically manage an isolated environment tied to the script itself.
For example, if you have a python file like this:
# example.py
import seaborn as sns
import matplotlib.pyplot as plt
# Sample data
data = sns.load_dataset("penguins").dropna()
# Plot using seaborn only
sns.scatterplot(data=data, x="flipper_length_mm", y="body_mass_g", hue="species")
plt.title("Flipper Length vs Body Mass by Species")
plt.show()
Run your script with seaborn in an isolated environment without installing anything globally:
uv run --with seaborn example.py
This eliminates the need for a separate requirements file and prevents pollution of your global or project environments.
Executing and Installing CLI Tools Like pipx
Tools like ruff, black, and isort are often used globally across projects. Installing them in the base environment can cause version conflicts or unnecessary clutter.
uvx runs CLI tools on demand in isolated environments, like pipx—but without needing to install them first.
To run ruff without installing it:
uvx ruff check example.py
Output:
All checks passed!
UV runs it in an isolated environment—no setup, no changes to your system.
Project Management Capabilities Like Poetry
Beyond handling single-file scripts, UV also provides full project management similar to Poetry. It can initialize new projects, manage dependency groups, and generate pyproject.toml
files.
To create a new project:
uv init
After running uv init
, the following files will be created:
.
├── .python-version
├── README.md
├── main.py
└── pyproject.toml
The main.py file contains a simple “Hello world” program. Try it out with uv run:
uv run main.py
Project structure:
.python-version
pins the Python version used for the projectREADME.md
provides a starting point for documenting your projectmain.py
is a simple entry-point script (e.g. “Hello world”)pyproject.toml
declares project metadata and dependencies in a modern, standard format
Typical dependency tasks with UV:
uv add pandas matplotlib # Install packages
uv remove matplotlib # Remove a package
uv add pandas --upgrade # Upgrade a package
uv sync # Install from pyproject.toml
Like Poetry, UV manages environments via pyproject.toml—but it’s faster thanks to its Rust-based backend.
A Drop-in Replacement for Pip, pip-tools, and Virtualenv
If you’re installing packages with pip, freezing requirements, or managing environments with virtualenv, you can adopt UV without changing your existing workflow.
UV uses familiar commands but runs them faster and more cleanly:
Creating a virtual environment:
uv venv
Activating the virtual environment:
- Unix/macOS:
source .venv/bin/activate
- Windows:
.venv\Scripts\activate
Installing packages:
uv pip install pandas scikit-learn
Deactivate a virtual environment:
deactivate
In each case, UV behaves predictably for Python developers familiar with pip and virtualenv, but with a noticeable speed boost.
Integration with Marimo
Marimo is a lightweight, reactive Python notebook framework for reproducible analysis and building data apps.
UV also supports Marimo for notebook-based workflows. You can launch a live editing session in a fully sandboxed environment like this:
uv run marimo edit notebook.py --sandbox
This makes it easy to prototype, explore data, or demonstrate code in a clean, reproducible workspace.
Final Thoughts
I used to be a fan of Poetry (here’s why)—until I discovered UV. It’s definitely worth your time: UV combines multiple tools into one cohesive experience and delivers superior speed.
For your next project, I recommend giving UV a try. It’s easy to learn and eliminates the overhead of switching between multiple Python tools.