How uv Simplified My Python Workflow

Table of Contents

I used to juggle different tools just to manage my Python environments. It was like trying to cook with one hand tied behind my back, pyenv for Python versions and virtualenv for environments. Then I discovered uv, and everything changed. Let me share how this one tool replaced my entire setup and made my workflow blazingly fast!

The Old Way: A Tool for Every Job

Before uv, my Python environment setup looked like this:

# Install Python version with pyenv
pyenv install 3.11.0
pyenv local 3.11.0

# Create virtual environment
python -m venv myproject_env

# Activate it (and remember to do this every time!)
source myproject_env/bin/activate

# Install dependencies
pip install -r requirements.txt

And when I wanted to switch projects? More commands:

# Deactivate current env
deactivate

# Switch to another project
cd ../other_project
source other_project_env/bin/activate

Don’t even get me started on sharing projects with colleagues—ensuring everyone had the same Python version and dependencies was a nightmare!

The Problems That Drove Me Crazy

  • Too many tools: pyenv, virtualenv, virtualenvwrapper—each with their own commands and quirks
  • Slow installations: pip installs could take forever, especially for large projects
  • Environment drift: Colleagues would have slightly different setups, leading to “works on my machine” issues
  • Mini-project chaos: For quick explorations, I’d either pollute my global environment or create separate venvs for each tiny experiment
  • Complex sharing: Getting a project running on someone else’s machine required pages of setup instructions

Enter uv: One Tool to Rule Them All

Then I found uv. It’s like if someone took the best parts of pip, virtualenv, and pyenv, mixed in some magic, and made it insanely fast. Here’s what changed:

# Initialize a new project
uv init myproject
cd myproject

# Install dependencies (blazingly fast!)
uv add requests pandas

# Run your code
uv run python main.py

That’s it! No activation, no version management, no separate tools. uv handles everything.

Sharing Projects Became Effortless

One of the biggest wins was sharing projects with colleagues. Before:

# Complex setup instructions
pyenv install 3.11.0
pyenv local 3.11.0
python -m venv env
source env/bin/activate
pip install -r requirements.txt

After:

# Just this!
uv sync

The uv sync command reads your pyproject.toml and uv.lock files, ensuring everyone gets exactly the same environment. No more “works on my machine” excuses!

Workspace Feature: Taming Mini-Projects

For my quick experiments and mini-projects, uv’s workspace feature is a game-changer. Instead of creating separate virtual environments for each tiny exploration:

# Old way: separate venv for each mini-project
mkdir experiment1 && cd experiment1
python -m venv venv1 && source venv1/bin/activate
pip install numpy

cd ../experiment2
python -m venv venv2 && source venv2/bin/activate
pip install pandas

Now I can group them in a workspace:

# pyproject.toml in workspace root
[tool.uv.workspace]
members = ["experiment1", "experiment2"]
# All experiments share the same fast environment
uv add numpy  # Available in all workspace projects
uv run --project experiment1 python script.py
uv run --project experiment2 python analysis.py

Perfect for when I’m exploring different libraries or testing ideas without the overhead of separate environments!

Following Best Practices Made Easy

I always tried to follow Python best practices—not using system Python, keeping dependencies isolated. But with the old tools, it was tedious. uv makes it effortless:

  • No system Python pollution: uv manages everything in its own isolated space
  • Dependency isolation: Each project gets its own environment automatically
  • Reproducible builds: Lock files ensure consistent installations
  • Fast dependency resolution: Way faster than pip

The Speed Difference Is Insane

Let me show you some real numbers from my experience:

Installing dependencies:

  • Old way: pip install -r requirements.txt → 2-3 minutes
  • New way: uv sync → 15-30 seconds

Creating new environments:

  • Old way: pyenv + venv setup → 1-2 minutes
  • New way: uv init → 5 seconds

Switching projects:

  • Old way: cd + source activate → Manual and error-prone
  • New way: uv run → Instant, with correct environment

Deployment and Building (Future-Proofing)

I haven’t tried this yet, but uv’s ability to deploy and build without third-party tools is exciting. No more Docker for simple deployments, no more complex CI/CD setups just to package Python apps. uv aims to handle the entire lifecycle from development to production.

Migration Tips for Others

If you’re still using the old stack, here’s how to migrate:

  1. Install uv: curl -LsSf https://astral.sh/uv/install.sh | sh
  2. Initialize existing projects: uv init in your project directory
  3. Migrate dependencies: uv add your current requirements
  4. Update your workflow: Replace venv activation with uv run
  5. Share the love: Tell your team about uv sync for consistent environments

Final Thoughts

uv didn’t just replace my tools—it revolutionized how I think about Python environment management. What used to be a complex, error-prone process is now simple, fast, and reliable. The best part? It’s actively developed by the same folks behind Ruff and other amazing Python tools.

If you’re still juggling multiple tools for Python environments, give uv a try. Your future self (and your colleagues) will thank you!

Happy coding!