Skip to content

How to sort Python imports with Ruff

This guide assumes you have uv installed. If not, see How to install uv first.

Ruff sorts imports through its linter, not its formatter. Select the I rule and apply fixes to sort the imports in a file or directory:

$ uvx ruff check --select I --fix .

To make import sorting a permanent part of a project, add the I rule under [tool.ruff.lint] in pyproject.toml:

[tool.ruff.lint]
extend-select = ["I"]

ruff check --fix . then sorts imports alongside every other enabled rule. The rest of this guide covers each path: the command, project configuration, a pre-commit hook, and organize-on-save in VS Code.

Why ruff format doesn’t sort imports

ruff format and ruff check do different jobs, and only ruff check sorts imports. The formatter rewrites code layout (indentation and line wrapping) to match a consistent style. Import order is a lint rule, I001, so it belongs to the linter.

Running the formatter on unsorted imports leaves them unsorted:

$ cat example.py
import pandas
import numpy as np

$ uvx ruff format example.py
1 file left unchanged
$ cat example.py
import pandas
import numpy as np

Running the linter with the I rule sorts them:

$ uvx ruff check --select I --fix example.py
Found 1 error (1 fixed, 0 remaining).
$ cat example.py
import numpy as np
import pandas

To both reorder imports and format the rest of the file, run the linter and the formatter:

$ uvx ruff check --select I --fix .
$ uvx ruff format .

Sort a single file or directory

To sort the imports in one file, pass its name:

$ uvx ruff check --select I --fix example.py

To sort every Python file in the current directory and its subfolders, pass .:

$ uvx ruff check --select I --fix .

--select I limits the run to import sorting and leaves every other lint rule off, which makes it a direct replacement for an isort invocation. The I prefix covers I001 (unsorted-imports), which reorders and groups imports, and I002 (missing-required-import), which adds any imports the project requires in every file. Drop --select I to run import sorting together with the rest of Ruff’s rules.

Add Ruff to a project for ongoing sorting

For repeated use, add Ruff as a development dependency instead of running it through uvx each time:

$ uv add --dev ruff

Enable the I rule with the [tool.ruff.lint] block shown at the top of this guide, then sort imports with:

$ uv run ruff check --fix .

Because the rule is enabled in configuration, --select I is no longer needed: ruff check sorts imports as part of its normal run. To customize grouping, add an [tool.ruff.lint.isort] section, for example known-first-party = ["my_package"].

Sort imports on every commit with pre-commit

To sort imports automatically before each commit, add Ruff to pre-commit. Create a .pre-commit-config.yaml with the ruff-check and ruff-format hooks:

repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.15.20
    hooks:
      - id: ruff-check
        args: [--select, I, --fix]
      - id: ruff-format

The ruff-check hook sorts imports (--select I --fix) and the ruff-format hook formats the rest of the file. They run in order, so imports are sorted before formatting. Install the hooks once:

$ uvx pre-commit install

From then on, committing a file with unsorted imports rewrites it and stops the commit so the changes can be staged:

$ git commit -m "Add data loader"
ruff check...............................................................Failed
- hook id: ruff-check
- files were modified by this hook

Found 1 error (1 fixed, 0 remaining).

ruff format..............................................................Passed

Stage the fixed file and commit again. If the I rule is already enabled in pyproject.toml, drop --select, I and use args: [--fix] so the hook applies every configured rule. Run uvx pre-commit autoupdate periodically to bump the rev: to the latest Ruff release.

Sort imports on save in VS Code

The Ruff extension (charliermarsh.ruff) can organize imports every time a Python file is saved. Add this to your settings.json:

{
    "[python]": {
        "editor.codeActionsOnSave": {
            "source.organizeImports.ruff": "explicit"
        }
    }
}

source.organizeImports.ruff runs Ruff’s import sorter on save. The .ruff suffix scopes the action to this extension, so it doesn’t trigger another organize-imports provider you have installed. The extension reads the project’s pyproject.toml, ruff.toml, or .ruff.toml, so the grouping matches what ruff check does on the command line.

To also format the file and apply other autofixes on save, set Ruff as the default formatter and add source.fixAll.ruff. See How to configure VS Code for a uv project for the full editor setup.

Learn More

Last updated on