Skip to content

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:

  1. You have unsorted imports in a file:
python
import os
import collections
  1. Run Ruff's formatter:
bash
ruff format file.py
# Output: 1 file left unchanged
  1. But running isort fixes the issue:
bash
isort file.py 
# Output: Fixing .../file.py

The 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:

bash
ruff check --select I --fix  # Sorts and categorizes imports
ruff format                 # Optional post-sort formatting

TIP

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:

toml
# Always sort imports when running 'ruff check'
extend-select = ["I"]

3. Important Notes

  • --fix applies automatic corrections when possible
  • Skip ruff format if you only need import sorting
  • Equivalent to isort with profile = "black" by default
  • Run ruff --help for rule customization options

Why This Works

Semantic Separation

Ruff separates responsibilities between its tools:

  • ruff check (Linter)
    Analyzes code structure (including imports)
    Handles rearrangements (I rules 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:

toml
[ruff]
extend-select = ["I"]

[lint.isort]
# Example customizations
required-imports = ["from __future__ import annotations"]
combine-as-imports = true

See all isort-equivalent settings in the Ruff documentation.

Additional References

Adopting this workflow ensures consistent, safe import sorting while leveraging Ruff's high performance and configurability.