TL;DR:

  • uv from Astral replaces pip, pip-tools, virtualenv, and pyenv with a single Rust-powered tool that’s 10–100x faster
  • ruff replaces flake8, black, isort, and several other linters in a single blazing-fast binary
  • pyright gives you fast, accurate type checking in your editor and CI pipeline without the slowness of mypy

If you’ve been using Python for a while, your mental model of the toolchain probably looks like: pip for packages, pyenv for version management, virtualenv for environments, flake8 and black for linting and formatting, maybe mypy for types. That stack works, but in 2026 there’s a dramatically faster, simpler alternative. Here’s how to switch.

uv: One Tool to Replace Five

uv is a Python package manager and project tool built by Astral (the same team behind Ruff). It’s written in Rust and is fast in a way that changes how you think about package operations. Installing a dependency is nearly instant. Creating a virtual environment takes milliseconds. Syncing a lockfile into a clean environment on CI takes seconds instead of minutes.

Installation:

curl -LsSf https://astral.sh/uv/install.sh | sh
# or via pip if you prefer
pip install uv

Replace pyenv with uv python:

# Install Python versions
uv python install 3.12
uv python install 3.11

# Pin a version for a project
uv python pin 3.12

Create projects:

# Create a new project (creates pyproject.toml, .python-version, a src layout)
uv init my-project
cd my-project

# Or init in an existing directory
uv init

Add and install packages:

# Add a dependency (updates pyproject.toml and uv.lock)
uv add requests
uv add pytest --dev

# Install/sync the environment
uv sync

# Run a command in the project environment without activating it
uv run python my_script.py
uv run pytest

Replace pip-compile with uv lock:

# Generate a lockfile from pyproject.toml
uv lock

# Install from lockfile (reproducible CI installs)
uv sync --frozen

The uv run command is particularly useful: you never have to manually activate a virtual environment. It detects the project’s environment and uses it automatically.

Ruff: One Linter to Rule Them All

Ruff is a Python linter and formatter written in Rust. It implements rules from flake8, isort, pyupgrade, pydocstyle, and several other tools, and it’s fast enough that you stop noticing it. Running on a large codebase in under a second changes how you think about linting — it becomes something you run constantly rather than something you tolerate in CI.

Install and configure:

Add to your pyproject.toml:

[tool.ruff]
target-version = "py312"
line-length = 88

[tool.ruff.lint]
select = [
    "E",    # pycodestyle errors
    "W",    # pycodestyle warnings
    "F",    # pyflakes
    "I",    # isort
    "UP",   # pyupgrade
    "B",    # flake8-bugbear
    "SIM",  # flake8-simplify
]
ignore = ["E501"]  # line too long — handled by formatter

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

Run it:

# Lint
uv run ruff check .

# Auto-fix what can be fixed
uv run ruff check --fix .

# Format (replaces black)
uv run ruff format .

# Check formatting without writing (for CI)
uv run ruff format --check .

Ruff’s formatter is intentionally black-compatible, so migrating an existing project that uses black is a drop-in swap. You get the same output, dramatically faster.

Pyright: Fast, Accurate Type Checking

mypy has been the standard Python type checker for years, but it’s slow and sometimes inconsistent. Pyright, Microsoft’s type checker (the same engine that powers Pylance in VS Code), is faster and in practice catches more errors.

Set up in pyproject.toml:

[tool.pyright]
pythonVersion = "3.12"
typeCheckingMode = "standard"  # or "strict" if you want to go all in
venvPath = "."
venv = ".venv"

Run from the command line:

uv add pyright --dev
uv run pyright

In VS Code, install the Pylance extension (it uses Pyright under the hood) and you get inline type errors without any additional configuration. In Neovim or other editors, use the pyright language server via your LSP configuration.

Type checking mode: standard checks annotated code and flags common issues. strict enforces that all code is annotated and is significantly more demanding — good for new projects, challenging to retrofit into existing codebases. Start with standard.

Putting It Together in CI

A complete GitHub Actions setup:

name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v3
        with:
          enable-cache: true
      - name: Install dependencies
        run: uv sync --frozen
      - name: Lint
        run: uv run ruff check .
      - name: Format check
        run: uv run ruff format --check .
      - name: Type check
        run: uv run pyright
      - name: Test
        run: uv run pytest

The setup-uv action handles caching the uv binary and the package cache. Combined with uv sync --frozen (which installs from the lockfile exactly), you get reproducible, fast CI installs.

What to Keep

You don’t have to migrate everything at once. The minimal starting point:

  1. Replace pip install with uv for your own development environment — immediate speed improvement, zero risk
  2. Add ruff check and ruff format to pre-commit, replacing flake8/black — takes 10 minutes to switch
  3. Add pyright for type checking incrementally — start with standard mode on a single module

The full migration from pip/pyenv/virtualenv to uv takes longer but pays back in CI time and onboarding friction reduction. New developers cloning your project run one command — uv sync — and they’re ready to go.

References