TL;DR
Ruff is a Python linter and formatter written in Rust that replaces Flake8, isort, Black, pyupgrade, and dozens more tools — all in one binary. It's 10-100x faster and supports 800+ lint rules.
What Is Ruff?
Ruff by Astral is the new standard for Python tooling:
- 100x faster — written in Rust, lints in milliseconds
- Drop-in replacement — for Flake8, isort, Black, pyupgrade, pydocstyle
- 800+ rules — the most comprehensive Python linter
- Auto-fix — automatically fixes most issues
- Built-in formatter — Black-compatible, 100x faster
- Free — MIT license
Quick Start
# Install
pip install ruff
# Lint
ruff check .
# Lint and auto-fix
ruff check --fix .
# Format (like Black, but faster)
ruff format .
Configuration
# pyproject.toml
[tool.ruff]
target-version = "py312"
line-length = 88
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"N", # pep8-naming
"UP", # pyupgrade
"B", # flake8-bugbear
"SIM", # flake8-simplify
"C4", # flake8-comprehensions
"DTZ", # flake8-datetimez
"RUF", # Ruff-specific rules
]
ignore = ["E501"] # line too long (handled by formatter)
[tool.ruff.lint.isort]
known-first-party = ["mypackage"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
What Ruff Replaces
| Old Tool | Ruff Equivalent | Rules |
|---|---|---|
| Flake8 |
E, W, F
|
pycodestyle + pyflakes |
| isort | I |
import sorting |
| Black | ruff format |
code formatting |
| pyupgrade | UP |
Python version upgrades |
| pydocstyle | D |
docstring conventions |
| flake8-bugbear | B |
common bugs |
| flake8-simplify | SIM |
code simplification |
| flake8-comprehensions | C4 |
better comprehensions |
| autoflake |
F401, F841
|
unused imports/variables |
| yesqa | RUF100 |
unused noqa comments |
Examples of What Ruff Catches
# Before ruff --fix
import os
import sys
import os # duplicate import
from typing import Optional, List
def process(data: Optional[List[str]] = None):
x = 1 # unused variable
items = []
for item in data or []:
items.append(item.upper()) # use list comprehension
if len(items) == 0: # use 'not items'
return None
return items
# After ruff --fix (auto-fixed!)
import sys
def process(data: list[str] | None = None):
items = [item.upper() for item in data or []]
if not items:
return None
return items
Pre-commit Hook
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
VS Code Integration
// .vscode/settings.json
{
"[python]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit",
"source.organizeImports.ruff": "explicit"
}
}
}
Speed Comparison
| Tool | CPython stdlib lint time |
|---|---|
| Ruff | 0.03s |
| Flake8 | 12s |
| Pylint | 60s+ |
| pyflakes | 3s |
Ruff is 400x faster than Flake8 on the CPython codebase.
Resources
Writing Python scrapers? My Apify tools provide production-ready web scraping — all linted with Ruff for clean, fast Python code. Questions? Email spinov001@gmail.com
Top comments (0)