Ruff
Ultra-fast Python linter and formatter written in Rust.
Ruff is an extremely fast Python linter and formatter written in Rust. It effectively replaces tools like Flake8, Black, isort, pydocstyle, pyupgrade, autoflake and many others, while offering performance improvements of 10x to 100x.
Why Adopt Ruff?
- Blazing speed: 10–100x faster than traditional Python linters due to its Rust architecture
- All-in-one solution: Combines linting, formatting and import sorting in a single tool
- Modern Python: Full support for Python 3.8+ with advanced type-hint handling
- Optimized for FastAPI: Built-in rules for async/await patterns and Pydantic models
- Seamless integration: Works with editors, CI/CD pipelines and pre-commit hooks
- Automatic fixes: Auto-fixes many style violations
Installation
sh
# Add Ruff as a development dependency
uv add --dev ruff
# Or install globally with uv
uv tool install ruff
# Alternative installation with pip
pip install ruffBasic Usage
sh
# Lint your code
uv run ruff check .
# Automatically fix fixable issues
uv run ruff check --fix .
# Format your code according to standards
uv run ruff format .
# Combined linting and formatting (recommended workflow)
uv run ruff check --fix . && uv run ruff format .
# Watch mode for development
uv run ruff check --watch .Configuration
Create a ruff.toml file at your project root or configure directly in pyproject.toml:
toml
# pyproject.toml
[tool.ruff]
target-version = "py38"
line-length = 88
exclude = [
".git",
".venv",
".mypy_cache",
".pytest_cache",
"__pycache__",
"build",
"dist",
]
show-fixes = true
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # Pyflakes (logical errors)
"I", # isort (import sorting)
"B", # flake8-bugbear (potential bugs)
"C4", # flake8-comprehensions
"UP", # pyupgrade (modernize code)
"ARG", # flake8-unused-arguments
"SIM", # flake8-simplify
"RUF", # Ruff-specific rules
]
ignore = [
"E501", # Line too long (handled by formatter)
"B008", # Function calls in default values (useful for FastAPI)
]
fixable = ["ALL"]
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = [
"S101", # Use of assert detected
"ARG", # Unused function arguments (fixtures)
]
"__init__.py" = [
"F401", # Unused import (re-export)
]
[tool.ruff.lint.isort]
split-on-trailing-comma = true
known-first-party = ["app", "core", "api"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
docstring-code-format = trueFastAPI-Specific Rules
toml
[tool.ruff.lint]
select = [
"ASYNC", # Async/await best practices
"FAST", # FastAPI-specific rules
"TRIO", # Async code best practices
"RUF006", # Detect mutations of default values
]
[tool.ruff.lint.per-file-ignores]
"app/api/**/*.py" = [
"B008", # Allow function calls in defaults (Depends(), Body(), etc.)
]VS Code Integration
Install the Ruff extension and add to your settings.json:
json
{
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit",
"source.organizeImports.ruff": "explicit"
}
},
"ruff.lint.args": ["--config=pyproject.toml"],
"ruff.format.args": ["--config=pyproject.toml"],
"ruff.enable": true,
"ruff.organizeImports": true
}PyCharm / IntelliJ Integration
- Install the Ruff plugin from the marketplace
- Configure in Settings > Tools > External Tools
- Add Ruff as an external formatter/linter
Pre-commit Hooks
yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.0
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- id: ruff-formatsh
pip install pre-commit
pre-commit install
pre-commit run --all-filesCI/CD — GitHub Actions
yaml
# .github/workflows/quality.yml
name: Code Quality
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
- name: Install dependencies
run: uv sync --dev --all-extras
- name: Run Ruff lint
run: uv run ruff check . --output-format=github
- name: Check formatting
run: uv run ruff format --check .CI/CD — GitLab CI
yaml
# .gitlab-ci.yml
ruff-lint:
stage: test
image: python:3.11
before_script:
- pip install uv
- uv sync --dev
script:
- uv run ruff check .
- uv run ruff format --check .
rules:
- if: $CI_MERGE_REQUEST_ID
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCHCI/CD — Jenkins Pipeline
groovy
pipeline {
agent any
stages {
stage('Quality Check') {
steps {
sh 'uv sync --dev'
sh 'uv run ruff check . || true'
sh 'uv run ruff format --check .'
}
}
}
}Common Workflows
sh
# Full quality check
uv run ruff check --fix .
uv run ruff format .
# Dry-run (no modifications)
uv run ruff check .
uv run ruff format --check .
# Run on specific files
uv run ruff check app/main.py app/models/
# Get rule explanation
uv run ruff rule F401
uv run ruff rule --all # List all rules
# Show violation statistics
uv run ruff check --statistics .
# Watch changes (only modified files)
uv run ruff check $(git diff --name-only --diff-filter=ACM | grep '\.py$')
# Show active configuration
uv run ruff check --show-settings
# Export configuration as JSON
uv run ruff check --show-settings --output-format=json > config.jsonPerformance Optimizations
For large projects, consider these optimizations:
toml
[tool.ruff]
# Enable cache (enabled by default)
cache-dir = ".ruff_cache"
# Respect .gitignore to limit search scope
respect-gitignore = truesh
# Parallel execution using multiple cores
RAYON_NUM_THREADS=8 uv run ruff check .
# Incremental analysis (only changed files)
uv run ruff check --diff $(git diff --name-only HEAD)Migration from Other Tools
Ruff eases migration from traditional tools:
sh
# Compare formatting with Black
ruff format --diff .
# Check isort compatibility
ruff check --select=I --diff .