TL;DR: Ruff is a Python code linting tool (linter + formatter) written in Rust. It runs 10-100x faster than Flake8 and can lint a massive project of 300,000 lines of code in just 0.5 seconds. By 2026, Ruff has become the de facto standard code quality tool in the Python ecosystem, adopted by major projects like Instagram, PyTorch, Jupyter, and Apache Airflow. This guide will walk you through using Ruff from scratch — including installation, configuration, and a complete migration guide from Flake8/Black/isort.
1. What is Ruff?
Ruff is developed by the Astral team (the same team behind uv) and written in Rust. It positions itself as an all-in-one code linting tool for the Python ecosystem, consolidating the functionality of multiple standalone tools:
| Replaced Tool | Function | Ruff Rule Prefix |
|---|---|---|
| Flake8 | Code style checking | F, E, W |
| Black | Code formatting | - |
| isort | Import sorting | I |
| pyupgrade | Python version upgrade suggestions | UP |
| pylint | Advanced code inspection | PL, SIM, C901 |
| autoflake | Auto-remove unused imports | F401, F841 |
Why is Ruff so fast?
- Rust compiled: Rust's performance far exceeds Python's, creating an order-of-magnitude difference in parsing speed.
- Parallel processing: Automatically leverages multi-core CPUs to scan files in parallel.
- Zero dependencies: No Python runtime needed — a single binary does it all.
- Incremental caching: Only checks changed files; subsequent runs are nearly instant.
Ruff's GitHub repository: https://github.com/astral-sh/ruff ⭐ Over 35,000 stars as of 2026.
2. Installing Ruff
Ruff supports multiple installation methods. We recommend using pip or the official install script:
# Method 1: pip (recommended)
pip install ruff
# Method 2: uv (faster)
uv tool install ruff
# Method 3: macOS Homebrew
brew install ruff
# Method 4: official install script
curl -LsSf https://astral.sh/ruff/install.sh | sh
# Verify installation
ruff --version
# Output: ruff 0.9.x
After installation, Ruff provides two main commands:
ruff check— code inspection (linter mode)ruff format— code formatting (formatter mode)
3. Quick Start: Check Your Project in 5 Minutes
Create a test file called hello.py:
import os
import sys
import json # unused
def hello_world():
x=1+2
print("hello world")
return x
if __name__ == "__main__":
hello_world()
3.1 Run Code Checking
ruff check hello.py
Example output:
hello.py:1:8: F401 [*] `os` imported but unused
hello.py:2:8: F401 [*] `sys` imported but unused
hello.py:3:8: F401 [*] `json` imported but unused
hello.py:5:1: W293 [*] Blank line contains whitespace
hello.py:7:6: E225 [*] Missing whitespace around operator
Found 5 errors.
[*] 5 fixable with the `--fix` option.
Ruff accurately identified 5 issues: 3 unused imports, 1 extra blank line, and 1 missing whitespace around an operator. Each error indicates whether it can be auto-fixed with --fix.
3.2 Auto-Fix
ruff check --fix hello.py
After running this, the file is automatically corrected:
def hello_world():
x = 1 + 2
print("hello world")
return x
if __name__ == "__main__":
hello_world()
3.3 Code Formatting
ruff format hello.py
ruff format works similarly to Black — it automatically adjusts indentation, blank lines, quote styles, and more, ensuring consistent code style across the entire project.
4. Configuration in Detail
Create a pyproject.toml in your project root to configure Ruff:
[tool.ruff]
# Target Python version
target-version = "py312"
# Line length limit
line-length = 88
# Directories to check
src = ["src", "tests"]
# Excluded directories
exclude = [
".git",
".venv",
"__pycache__",
"build",
"dist",
]
[tool.ruff.lint]
# Enabled rule sets
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort (import sorting)
"UP", # pyupgrade (version upgrade suggestions)
"B", # flake8-bugbear (common bug patterns)
"SIM", # flake8-simplify (code simplification)
"RUF", # Ruff's own rules
]
# Ignored rules
ignore = [
"E501", # Line too long (leave this to the formatter)
"E402", # Import not at top of file (needed in some scripts)
]
# Maximum allowed complexity
mccabe.max-complexity = 10
[tool.ruff.lint.per-file-ignores]
# Ignore certain rules in test files
"tests/**/*.py" = ["S101", "PLR2004"]
# Ignore all rules in migration files
"**/migrations/*.py" = ["ALL"]
[tool.ruff.format]
# Quote style: single or double
quote-style = "double"
# Indentation type
indent-style = "space"
# Trailing newline
skip-magic-trailing-comma = false
4.1 Common Rule Set Reference
| Rule Set | Description | Typical Rules |
|---|---|---|
| E/W | pycodestyle style checks | E501 line too long, W292 missing newline at end of file |
| F | pyflakes error detection | F401 unused import, F841 unused variable |
| I | import sorting | I001 imports not sorted correctly |
| UP | Python version upgrades | UP006 use list instead of typing.List |
| B | bugbear common bugs | B006 mutable default argument, B007 unused loop variable |
| SIM | code simplification | SIM101 duplicate isinstance, SIM108 use ternary expression |
| RUF | Ruff's own rules | RUF001 ambiguous character, RUF005 prefer unpacking over concatenation |
5. Complete Migration Guide: Replacing Black/isort/Flake8
If your project previously used the Black + isort + Flake8 combination, you can fully migrate to Ruff.
5.1 Uninstall Old Tools
pip uninstall black isort flake8 autoflake pyupgrade -y
5.2 Configure Ruff for Compatibility
Add Black-compatible settings in pyproject.toml:
[tool.ruff]
line-length = 88 # Black default line width
target-version = "py312"
[tool.ruff.format]
quote-style = "double" # Black default double quotes
indent-style = "space"
[tool.ruff.lint]
select = ["E", "W", "F", "I"]
5.3 Batch-Fix the Entire Project
# Step 1: format all Python files
ruff format .
# Step 2: check and auto-fix
ruff check --fix .
# Step 3: review remaining issues (no auto-fix)
ruff check .
5.4 Integrate with pre-commit
Create a .pre-commit-config.yaml:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.0
hooks:
# Format first
- id: ruff-format
# Then check
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Install the pre-commit hook:
pip install pre-commit
pre-commit install
Now, every time you run git commit, Ruff will automatically format and check staged files.
6. CI/CD Integration
6.1 GitHub Actions
name: Ruff Check
on: [push, pull_request]
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install Ruff
run: pip install ruff
- name: Run Ruff format check
run: ruff format --check .
- name: Run Ruff lint
run: ruff check --output-format=github .
6.2 GitLab CI
ruff:
image: python:3.12-slim
stage: test
script:
- pip install ruff
- ruff format --check .
- ruff check .
allow_failure: true # Allow failures initially during transition
6.3 Performance Optimization for Large Projects
For very large projects, consider these optimization strategies:
# Only check changed files (CI scenario)
ruff check --diff .
# Output SARIF format (for GitHub Code Scanning)
ruff check --output-format=sarif . > results.sarif
# Check only specific rules
ruff check --select=F,E .
# View Ruff configuration and cache status
ruff check --show-settings .
7. Ruff vs. Competitors
| Feature | Ruff | Flake8 | Black + isort |
|---|---|---|---|
| Language | Rust | Python | Python |
| Speed | ⚡ Extremely fast (milliseconds) | Slow (seconds) | Moderate |
| Scope | Linter + Formatter | Linter only | Formatter only |
| Plugin Ecosystem | Built-in rules | Rich plugins | Plugin extensions |
| Auto-Fix | ✅ Supported | ❌ Not supported | ✅ Supported |
| Configuration | pyproject.toml | .flake8/.cfg | pyproject.toml |
| Python Dependency | No Python needed | Required | Required |
Real-World Performance Benchmarks
In a project with 500,000 lines of code:
- Ruff check: 0.3 seconds
- Flake8: 45 seconds
- pylint: 120 seconds
Ruff is roughly 150x faster than Flake8 and 400x faster than pylint.
8. Advanced Usage
8.1 Custom Rules
Ruff lets you customize rule severity through pyproject.toml:
[tool.ruff.lint]
select = ["E", "F", "W"]
# Set certain rules as warnings instead of errors
[tool.ruff.lint.flake8-errmsg]
max-string-length = 20
[tool.ruff.lint.pydocstyle]
convention = "google" # or "numpy", "pep257"
8.2 IDE Integration
VS Code: Install the official Ruff extension for: - Real-time lint checking - Auto-format on save - One-click fix suggestions
// .vscode/settings.json
{
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit"
}
}
}
PyCharm: Configure via External Tools:
- Open Settings → Tools → External Tools
- Add Ruff: Program = ruff, Arguments = check --fix $FilePath$
8.3 Incremental Checking (Watch Mode)
# Watch for file changes and re-check automatically
ruff check --watch .
8.4 Generate HTML Reports
# Output JSON format, processable with jq
ruff check --output-format=json . | jq '.'
# Or use SARIF format for GitHub Code Scanning
ruff check --output-format=sarif . > ruff-results.sarif
9. FAQ
Q1: Can Ruff completely replace Flake8?
In most scenarios, yes. Ruff has most of Flake8's built-in rules (E, W, F series) plus rules from popular plugins (bugbear, eradicate, etc.). However, if you rely on a very niche Flake8 plugin, you may want to verify whether Ruff has an equivalent.
Q2: Can Ruff replace pylint?
Not entirely. Ruff focuses on code style and common bug detection, while pylint offers deeper code quality analysis (e.g., complexity scoring, duplicate code detection). For day-to-day development, Ruff is more than sufficient. For strict quality audits, consider using Ruff alongside pylint.
Q3: Is Ruff's --fix safe?
Very safe. Ruff's auto-fix only applies to rules with well-defined fix strategies — it never makes semantic changes. Before applying fixes, it's a good idea to preview changes with ruff check --diff ..
Q4: Which Python versions does Ruff support?
Ruff itself supports code checking for Python 3.7 through 3.13. With the target-version config, you can specify your target Python version and receive relevant upgrade suggestions.
10. Summary
Ruff is becoming the code quality infrastructure of the Python ecosystem. Thanks to the blazing performance of Rust, a rich set of built-in rules, and an all-in-one linter + formatter experience, it makes Python project code quality management simpler and more efficient than ever before.
Action Plan:
- Install with
pip install ruff - Run
ruff check --fix .+ruff format .in your project - Configure
pyproject.tomlto customize rules - Integrate into pre-commit and your CI/CD pipeline
Your project's code quality will see a massive improvement — and the whole process takes just a few minutes.
Related Links:
- Ruff Official Docs: https://docs.astral.sh/ruff/
- Ruff GitHub: https://github.com/astral-sh/ruff
- uv Tool (same team as Ruff): https://docs.astral.sh/uv/
- Related: linux-tutorials/linux-fileformat.md — Learn about Python file formats
- Related: linux-tutorials/ubuntu-dependency.md — Python package management basics