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
| Tool | Ruff Equivalent |
|---|---|
| Flake8 | ruff check |
| isort | ruff check --select I |
| pyupgrade | ruff check --select UP |
| Black | ruff format |
| autoflake | ruff 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
- Rust: Native code, no Python overhead
- Parallel downloads: Fetch packages concurrently
- Caching: Global cache, shared across projects
- 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
- Not all Pylint rules (but growing)
- Some flake8 plugins not yet ported
- Different output format (may break scripts)
uv
- Relatively new (test thoroughly)
- Some edge cases with complex dependencies
- Not yet a full project manager (like Poetry)
The Future
Astral is building a complete Python toolchain in Rust:
- ✅ Ruff (linting, formatting)
- ✅ uv (package management)
- 🔄 Full project management
- 🔄 Python version management
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.