Ultraviolet and Ruff: The New Python Tooling Speed

python dev

Astral’s Ruff (linter) and uv (package manager) are redefining Python tooling speed. Written in Rust, they’re orders of magnitude faster. Here’s why it matters.

The Speed Difference

Ruff vs Traditional Linters

# Pylint on medium codebase
time pylint src/
# real    45.2s

# Flake8
time flake8 src/
# real    8.3s

# Ruff
time ruff check src/
# real    0.3s

100x+ faster is not an exaggeration.

uv vs pip

# pip install
time pip install -r requirements.txt
# real    32.4s

# uv install
time uv pip install -r requirements.txt
# real    2.1s

15x faster, and it gets better with caching.

Ruff: The Universal Linter

Installation

pip install ruff
# or
brew install ruff
# or
cargo install ruff

Basic Usage

# Lint
ruff check .

# Fix auto-fixable issues
ruff check --fix .

# Format (ruff has a formatter too)
ruff format .

What It Replaces

ToolRuff Equivalent
Flake8ruff check
isortruff check --select I
pyupgraderuff check --select UP
Blackruff format
autoflakeruff check --select F

One tool, one config, one pass.

Configuration

# pyproject.toml
[tool.ruff]
line-length = 100
target-version = "py311"

[tool.ruff.lint]
select = [
    "E",   # pycodestyle errors
    "W",   # pycodestyle warnings
    "F",   # pyflakes
    "I",   # isort
    "B",   # flake8-bugbear
    "C4",  # flake8-comprehensions
    "UP",  # pyupgrade
]
ignore = ["E501"]  # line too long

[tool.ruff.lint.isort]
known-first-party = ["myproject"]

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

Pre-commit Integration

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.3.0
    hooks:
      - id: ruff
        args: [--fix]
      - id: ruff-format

uv: The Fast Package Manager

Installation

curl -LsSf https://astral.sh/uv/install.sh | sh
# or
pip install uv

Drop-in Replacement

# Instead of pip
uv pip install requests
uv pip install -r requirements.txt
uv pip freeze > requirements.txt

# Instead of pip-compile
uv pip compile requirements.in -o requirements.txt

Virtual Environment

# Create venv
uv venv

# Activate (same as before)
source .venv/bin/activate

# Install
uv pip install -e ".[dev]"

Why It’s Faster

  1. Rust: Native code, no Python overhead
  2. Parallel downloads: Fetch packages concurrently
  3. Caching: Global cache, shared across projects
  4. Resolution: Optimized dependency resolver

Compatibility

# Works with existing
uv pip install -r requirements.txt  # Standard requirements
uv pip install -e .                  # Editable installs
uv pip install package[extra]        # Extras

CI/CD Impact

Before

# GitHub Actions
- name: Install dependencies
  run: pip install -r requirements.txt
  # ~60 seconds

After

- name: Install uv
  uses: astral-sh/setup-uv@v1

- name: Install dependencies
  run: uv pip install -r requirements.txt
  # ~5 seconds

10x faster CI builds add up.

Linting

- name: Lint
  run: ruff check .
  # ~1 second instead of ~30 seconds

Development Workflow

Fast Iteration

# Save file → lint → feedback
# With ruff: instant
# With pylint: wait...

# Install new dependency
# With uv: instant
# With pip: wait...

Speed improves developer experience measurably.

Project Setup with uv

# Create project
mkdir myproject && cd myproject
uv venv
source .venv/bin/activate

# Add dependencies
echo "django>=5.0" >> requirements.in
uv pip compile requirements.in -o requirements.txt
uv pip install -r requirements.txt

# Add dev dependencies
echo "-c requirements.txt\npytest\nruff" > requirements-dev.in
uv pip compile requirements-dev.in -o requirements-dev.txt
uv pip install -r requirements-dev.txt

Migration Guide

From Flake8 + isort + Black

# Remove from pyproject.toml:
# [tool.flake8]
# [tool.isort]  
# [tool.black]

# Add:
[tool.ruff]
line-length = 88

[tool.ruff.lint]
select = ["E", "F", "I", "W"]

[tool.ruff.format]
quote-style = "double"
# Remove old tools
pip uninstall flake8 isort black

# Install ruff
pip install ruff

# Update pre-commit
# ... (see pre-commit config above)

From pip to uv

# No project changes needed
# Just use uv instead of pip
alias pip="uv pip"

# Or explicitly
uv pip install -r requirements.txt

Editor Integration

VS Code

// settings.json
{
    "python.linting.enabled": true,
    "ruff.enable": true,
    "ruff.lint.run": "onType",
    "editor.formatOnSave": true,
    "[python]": {
        "editor.defaultFormatter": "charliermarsh.ruff"
    }
}

PyCharm

Ruff plugin available in marketplace.

Limitations

Ruff

uv

The Future

Astral is building a complete Python toolchain in Rust:

The goal: one fast tool for all Python development needs.

Final Thoughts

Speed is a feature. Waiting for tools is friction. Ruff and uv remove that friction.

Try them. The speed difference is immediately noticeable.


Faster tools, happier developers.

All posts