How to migrate to Ruff¶
The stack migrated from isort + black + flake8 to Ruff as a unified tool for linting, formatting, and import sorting. This guide shows the configuration and how to run the checks.
Why Ruff¶
| Aspect | Before (isort + black + flake8) | Ruff |
|---|---|---|
| Speed | ~10-30 s | 10-100× faster (Rust) |
| Tools | 3 + plugins | 1 single binary |
| Configuration | 3 sections | 1 single [tool.ruff] |
| Active rules | Limited | 700+ ported and unified |
| Auto-fix | Partial | Mostly automatic |
The trigger was a blocking bug in the ms-python.isort extension with Python 3.12 on Windows (PackageNotFoundError, LSP crash -32097).
Applied configuration¶
In pyproject.toml:
[tool.ruff]
line-length = 100
target-version = "py312"
[tool.ruff.lint]
select = ["E", "W", "F", "I", "UP", "B"]
ignore = []
[tool.ruff.lint.isort]
known-first-party = ["domains", "tools", "core", "src"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
| Rule | Origin | What it detects |
|---|---|---|
| E/W | pycodestyle | Style errors/warnings |
| F | pyflakes | Unused imports/names/variables |
| I | isort | Import sorting |
| UP | pyupgrade | PEP 585/604 modernization |
| B | flake8-bugbear | Subtle bugs (mutable defaults, zip without strict=) |
Local workflow¶
ruff check . # lint (daily use)
ruff check . --fix # safe auto-fixes
ruff check . --select I001 --fix # imports only
ruff format . # format (drop-in for black)
ruff format --check . # CI mode (fails if formatting needed)
ruff check . --statistics # per-rule stats
CI (GitHub Actions)¶
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements-dev.txt
- run: ruff check . --output-format=github
- run: ruff format --check .
--output-format=github produces native PR annotations.
Migrate VSCode from isort to Ruff¶
.vscode/settings.json:
{
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
}
}
}
Single provider per category
Stack policy: a single provider for lint/format/imports (charliermarsh.ruff). Forbidden (redundant) extensions: ms-python.black-formatter, ms-python.flake8, ms-python.pylint, ms-python.autopep8.
Apply fixes in phases¶
Applying all auto-fixes in one commit creates too much noise. Recommended plan:
- Imports (low risk):
ruff check . --select I001 --fix - Types (low-medium risk):
ruff check . --select UP --fix - F + B (manual review):
ruff check . --select F,B→ review →--fix --unsafe-fixes - Format (last):
ruff format .
See also¶
- Contributing — commit conventions.
Canonical source
Derives from docs/shared/RUFF_MIGRATION.md.