Dev Encyclopedia
ArticlesTools

Get notified when new content drops

No spam. Just new articles, tools, and updates — straight to your inbox.

Dev Encyclopedia

A reference for builders

Content

  • Articles
  • Tools
  • Contact

Connect

  • support@devencyclopedia.com
  • RSS Feed

© 2026 Dev Encyclopedia

Privacy PolicyTermsDisclaimer
  1. Home
  2. /Blog
  3. /How to Switch to uv: Replace pip, virtualenv, and Poetry in Your Python Project
python10 min read

How to Switch to uv: Replace pip, virtualenv, and Poetry in Your Python Project

uv replaces pip, virtualenv, and Poetry with a single fast binary. Step-by-step guide to migrating your existing Python project and setting up GitHub Actions CI.

By Dev EncyclopediaPublished June 4, 2026
On this page

On this page

  • Install uv
  • Migrate from pip + requirements.txt
  • Migrate from Poetry
  • Run Your Project
  • Pin Your Python Version
  • GitHub Actions CI
  • Frequently Asked Questions

Python package management has always been too complicated. To do it properly you needed pip to install packages, virtualenv or venv to isolate environments, pyenv to manage Python versions, and pip-tools to generate a proper lockfile. That's four separate tools, four different config formats, and four things that can break in CI.

uv fixes all of that. It's a single Rust binary from Astral (the same team that built ruff) that handles everything. Not "a little faster" fast — we're talking 10 to 100 times faster than pip on cold installs, and near-instant on warm ones.

This guide is specifically for migrating an existing project. If you're starting fresh, the workflow is even simpler — but most of us have a requirements.txt or pyproject.toml that needs to come along for the ride.

💡 TL;DR

Install uv with curl -LsSf https://astral.sh/uv/install.sh | sh, run uv init in your project root, import your dependencies, then use uv run instead of activating a virtual environment.

What uv Replaces

Old tooluv equivalent
`pip install requests``uv add requests`
`python -m venv .venv``uv venv`
`pyenv install 3.12``uv python install 3.12`
`pip-compile requirements.in``uv lock`
`pip install -r requirements.txt``uv sync`
  1. 1

    Install uv

    You don't need Python installed to install uv. It's a standalone binary.

    bash
    curl -LsSf https://astral.sh/uv/install.sh | sh

    On Windows (PowerShell):

    powershell
    powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

    Restart your terminal and run uv --version to confirm.

  2. 2

    Migrate from pip + requirements.txt

    Navigate to your project root and initialize uv:

    bash
    uv init

    This creates a pyproject.toml if you don't already have one. Then import your existing requirements. If your requirements.txt is clean (no comments, no extras), you can do it in one line:

    bash — Quick import
    uv add $(cat requirements.txt | grep -v "^#" | xargs)

    Or use uv's pip-compatible interface for a file with pinned versions, comments, or extras:

    bash — Safe alternative
    uv pip install -r requirements.txt

    After that, run uv lock to generate your lockfile. Commit both pyproject.toml and uv.lock. Going forward, use uv add package-name instead of pip install, and uv run python script.py instead of activating the virtual environment manually.

    💡 Tip

    The lockfile uv.lock should be committed to your repo. This is the opposite of what some tools recommend for lockfiles — uv's lockfile is what guarantees every developer and every CI run installs the exact same versions.

  3. 3

    Migrate from Poetry

    The easiest path is a tool called migrate-to-uv, which runs via uvx (uv's tool runner, like npx for Python):

    bash
    uvx migrate-to-uv

    Run it in your project root. It reads your pyproject.toml (Poetry format) and converts it to the uv format. Then rebuild:

    bash
    uv lock && uv sync

    A few things that don't auto-migrate cleanly:

    • Optional dependency groups: Poetry uses [tool.poetry.group.dev.dependencies]. uv uses [dependency-groups] with slightly different syntax. Check these manually after migration.
    • Private indexes: If your Poetry config references a private PyPI index, set it up in [tool.uv.sources] in your new pyproject.toml.
    • poetry run calls: Replace all poetry run X with uv run X across your scripts and documentation.
  4. 4

    Run Your Project

    Once uv is managing your project, use uv run for everything. You don't need to activate the virtual environment manually:

    bash
    # Instead of: source .venv/bin/activate && python main.py
    uv run python main.py
    
    # Instead of: source .venv/bin/activate && pytest
    uv run pytest
    
    # Instead of: source .venv/bin/activate && flask run
    uv run flask run

    ℹ Info

    If you prefer activating the environment, the .venv folder is still there at your project root. source .venv/bin/activate works exactly as before. uv run is just more convenient for one-off commands.

  5. 5

    Pin Your Python Version

    To pin a specific Python version for your project, create a .python-version file in your project root. uv reads this file automatically:

    bash
    echo "3.12" > .python-version

    You can also install that Python version via uv if it's not already on your system:

    bash
    uv python install 3.12

    💡 Tip

    Commit .python-version to your repo. This ensures everyone on the team and all CI runs use the same Python version without needing pyenv or any other version manager.

  6. 6

    GitHub Actions CI

    This is where uv's speed pays off most visibly. CI recreates your environment from scratch on every run — the difference between pip and uv is often 2 to 3 minutes vs 15 to 20 seconds.

    yaml — .github/workflows/ci.yml
    name: CI
    on: [push, pull_request]
    jobs:
      test:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: astral-sh/setup-uv@v4
          - name: Install Python
            run: uv python install
          - name: Install dependencies
            run: uv sync --frozen
          - name: Run tests
            run: uv run pytest tests/

    ⚠ Warning

    The --frozen flag is critical. It tells uv to use uv.lock exactly as committed and fail the build if the lockfile is out of date. Without it, CI could silently install different versions than your lockfile specifies.

Frequently Asked Questions

How much faster is uv than pip?

In benchmarks, uv installs packages 10 to 100 times faster than pip on cold cache and near-instant on warm cache. The difference is most noticeable in CI where the cache is cold on every run.

Scenariopipuv
Install Django cold~45 seconds~3 seconds
Install Django warm~8 seconds<1 second
Full data science stack cold~4 minutes~15 seconds
Should I commit uv.lock to my repository?

Yes — always commit uv.lock. It records the exact resolved versions of every dependency (including transitive ones). Without it, two developers running uv sync at different times might install different patch versions of a dependency, leading to 'works on my machine' bugs.

💡 Tip

The only time you'd exclude uv.lock from a repo is for a library package (not an application) that intentionally supports a range of dependency versions. For applications and services, always commit the lockfile.

Does uv support monorepos and workspaces?

Yes. uv supports workspaces similar to Cargo (Rust) and npm workspaces. Define workspace members in your root pyproject.toml:

toml
[tool.uv.workspace]
members = ["packages/*"]

Each member has its own pyproject.toml, but they share a single uv.lock at the workspace root. Dependencies are resolved together, preventing version conflicts across packages.

How do I add a dev-only dependency with uv?

Use the --dev flag:

bash
uv add --dev pytest ruff mypy

This adds the package to the [dependency-groups] dev section of pyproject.toml rather than the main [project.dependencies]. Dev dependencies are installed with uv sync (default) but excluded when you do uv sync --no-dev for production deploys.

Can uv replace pipx for globally installed tools?

Yes. Use uv tool install to install CLI tools globally:

bash
uv tool install ruff
uv tool install black
uv tool install httpie

Installed tools are isolated from each other and from your projects. Use uvx tool-name to run a tool once without installing it permanently — the equivalent of npx in the JavaScript ecosystem.

On this page

  • Install uv
  • Migrate from pip + requirements.txt
  • Migrate from Poetry
  • Run Your Project
  • Pin Your Python Version
  • GitHub Actions CI
  • Frequently Asked Questions