Sorting Imports Alphabetically with Ruff
Problem Statement
When migrating to Ruff for Python code formatting, many developers expect running ruff format to automatically sort imports alphabetically—similar to isort. Here's a common scenario:
- You have unsorted imports in a file:
import os
import collections- Run Ruff's formatter:
ruff format file.py
# Output: 1 file left unchanged- But running
isortfixes the issue:
isort file.py
# Output: Fixing .../file.pyThe core issue: Ruff handles import sorting during linting rather than formatting. The formatter (ruff format) maintains AST fidelity (it won't rearrange imports), while import sorting is implemented through linting rules (the I prefix rules).
Solution
To achieve alphabetical import sorting with Ruff, use these steps:
1. Basic Command
Run the linter with import-focused rules:
ruff check --select I --fix # Sorts and categorizes imports
ruff format # Optional post-sort formattingTIP
You can combine both commands in one line:ruff check --select I --fix && ruff format
2. Permanent Configuration
Add to your ruff.toml to enable import sorting automatically:
# Always sort imports when running 'ruff check'
extend-select = ["I"]3. Important Notes
--fixapplies automatic corrections when possible- Skip
ruff formatif you only need import sorting - Equivalent to
isortwithprofile = "black"by default - Run
ruff --helpfor rule customization options
Why This Works
Semantic Separation
Ruff separates responsibilities between its tools:
ruff check(Linter)
Analyzes code structure (including imports)
Handles rearrangements (Irules modify AST)ruff format(Formatter)
Only adjusts whitespace/style
Maintains AST integrity (won't reorganize imports)
WARNING
Sorting imports changes code semantics:
- Affects import precedence
- Alters implicit execution order
- Modifies symbol table entries
Ruff avoids this during formatting to prevent unintended behavior.
Customizing Import Rules
Extend rules in your config file:
[ruff]
extend-select = ["I"]
[lint.isort]
# Example customizations
required-imports = ["from __future__ import annotations"]
combine-as-imports = trueSee all isort-equivalent settings in the Ruff documentation.
Additional References
- Ruff: Sorting Imports Docs
- Formatters vs. Linters
- Upcoming Import Sorting Improvements (Future release tracking)
Adopting this workflow ensures consistent, safe import sorting while leveraging Ruff's high performance and configurability.