DEV Community

Cover image for From Pip to Lightning: How uv Opened My Eyes to Better Python Workflows
Vivek Pathania
Vivek Pathania

Posted on

From Pip to Lightning: How uv Opened My Eyes to Better Python Workflows

If you build LLM agents, fine-tune models, or stitch together vector stores and APIs—uv will save you time, reduce friction, and simplify your stack.


The Problem with Python for AI Projects

When you're building AI agents or orchestration systems, you're not just writing code. You're juggling:

  • transformers, langchain, llama-index, openai, pydantic, torch, uvicorn, numpy, and twenty others.
  • Environments across local dev, notebooks, cloud functions, Docker containers.
  • Rapid iteration cycles and fast-moving dependencies.
  • Dependency conflicts and compatibility issues.

For a long time, I used pip, venv, and pip-tools. They worked—until they didn't.

Eventually, I hit the wall. And then I found uv.


The Day I Realized I Was Doing It All Wrong

I was working on two of my personal AI projects:

  1. MCP SQL Server – a lightweight server that lets LLM agents interact with SQL databases.
  2. MCP SQL Chatbot & Dashboard – a project that combines natural language querying with an interactive dashboard.

Both were pushing the limits of what I could manage with pip, pip-tools, and venv. Every time I touched a dependency, something broke. Docker builds got bloated. Dev setup instructions kept growing.

Then I tried uv. Within 20 minutes, I had:

  • Killed off my requirements.txt
  • Replaced multiple tools with one
  • Cut my Docker build time by over half

It felt like I had been living under a rock. I genuinely couldn’t believe how much simpler Python dev could be.


Why I Ditched Pip and Adopted uv

1. uv is Unreasonably Fast

Installing heavy packages like torch or sentence-transformers used to take 30+ seconds. With uv, it's often done in under 2 seconds. No exaggeration.

2. One Tool for Everything

uv replaces:

  • pip
  • virtualenv
  • pip-tools
  • pipx
  • poetry
  • pyenv
  • twine

And it's fast at every step.

3. Reproducibility Just Works

With pyproject.toml and uv.lock, your environments are consistent across machines, platforms, and Python versions.


What Is uv, Really?

"A single tool to replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more."

Built in Rust by Astral (creators of ruff), uv isn't a wrapper—it's a full rethinking of Python packaging, designed for speed and simplicity.


My Workflow with uv (No More requirements.txt)

uv init agentlab
cd agentlab
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zu5q8l793xmrn266etcp.png)
uv add langchain openai llama-index sentence-transformers
uv run app.py
Enter fullscreen mode Exit fullscreen mode

Want to add dev-only packages?

uv add --dev pytest black
Enter fullscreen mode Exit fullscreen mode

Upgrade everything?

uv lock --upgrade
uv sync
Enter fullscreen mode Exit fullscreen mode

Need Python 3.11?

uv venv .venv --python 3.11
Enter fullscreen mode Exit fullscreen mode

Managing Packages with uv pip

Stick to the interface you know:

uv pip install transformers
uv pip uninstall numpy
uv pip freeze
Enter fullscreen mode Exit fullscreen mode

Same syntax, faster performance, better reproducibility.


Running Python Code with uv run

No need to activate .venv. Just run:

uv run train.py
uv run python scripts/agent_cli.py
uv run pytest
Enter fullscreen mode Exit fullscreen mode

This syncs your environment and runs the command in one go. Useful in CI scripts, notebooks, or any dev loop.


uv sync: The Backbone of Everything

uv sync
Enter fullscreen mode Exit fullscreen mode

This one command:

  • Installs Python if needed
  • Sets up .venv
  • Installs dependencies
  • Updates the lock file

It replaces:

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

uvx: Disposable Tools On-Demand

Want to run a CLI tool without cluttering your environment?

uvx pycowsay "Hello from uv"
uvx django-admin startproject newapp
Enter fullscreen mode Exit fullscreen mode

In my MCP projects, I used uvx to test tools and setup scripts without polluting my main environment. This saved me countless hours cleaning up old installs or reverting accidental global changes.


Dev vs Prod Dependencies and CI Integration

One of the best features in uv is how it handles dependency groups. These let you clearly separate packages based on how and where they’re used—keeping your production environments lean and your development environments rich.

uv supports named groups, like dev, prod, testing, or even custom ones like notebooks, viz, or docker. By default, there’s an implicit main group for core dependencies.

Here’s how you might organize them:

  • main: core app dependencies (e.g., langchain, llama-index)
  • dev: tools used in development (e.g., pytest, jupyter, black)
  • prod: deployment-time packages (e.g., gunicorn, uvicorn)
  • notebooks: interactive and experimental tools (e.g., matplotlib, pandas)

Adding packages to groups

uv add --dev jupyterlab
uv add --group prod fastapi gunicorn
uv add --group notebooks seaborn plotly
Enter fullscreen mode Exit fullscreen mode

This updates your pyproject.toml:

[project]
dependencies = [
  "llama-index",
  "langchain"
]

[dependency-groups.dev]
dependencies = [
  "jupyterlab"
]

[dependency-groups.prod]
dependencies = [
  "gunicorn",
  "fastapi"
]

[dependency-groups.notebooks]
dependencies = [
  "seaborn",
  "plotly"
]
Enter fullscreen mode Exit fullscreen mode

Installing specific groups

uv sync --no-group dev --group prod
uv sync --group dev --group notebooks
uv sync --no-group dev
Enter fullscreen mode Exit fullscreen mode

Using Groups in GitHub Actions (CI/CD)

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install uv
        run: |
          curl -LsSf https://astral.sh/uv/install.sh | sh
      - name: Sync only prod dependencies
        run: |
          uv sync --no-group dev --group prod
      - name: Run tests
        run: uv run pytest
Enter fullscreen mode Exit fullscreen mode

Docker-Friendly by Design

ENV UV_PROJECT_ENVIRONMENT=/code/.venv
COPY pyproject.toml uv.lock /_lock/
RUN cd /_lock && uv sync --frozen --no-group dev --group prod
Enter fullscreen mode Exit fullscreen mode

Cheatsheet: uv vs Traditional Tools

Operation Traditional Tool uv Equivalent
Install Python pyenv, apt, brew uv python install 3.11
Create venv python -m venv .venv uv venv .venv
Install packages pip install uv pip install
Compile lockfile pip-compile uv pip compile
Sync environment pip install -r requirements.txt uv sync
Add dev package Manual edit + install uv add --dev
Run Python in env source .venv && python uv run
Use CLI tool temporarily pipx run uvx tool

Final Thoughts

uv didn’t just save me time. It changed how I think about Python environments.

If you're building AI agents or ML workflows and are tired of the friction in Python's toolchain, give uv a shot. It's fast, clean, and it finally feels like modern Python environment management was done right.

I ditched pip, requirements.txt, and even virtualenv workflows. I haven’t looked back.


Resources

Top comments (0)