Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Black formats Python, isort sorts imports, and Ruff checks code for issues—and can also format files and sort imports. For a new project, Ruff can often handle all three jobs with one configuration. Existing projects can keep Black and isort alongside Ruff; the key is to give each task one clear owner and make local checks match CI.

What linting, formatting, and import sorting each do

These tools address different kinds of code quality. A formatter changes presentation, such as indentation, spacing, quotes, and line breaks. An import sorter groups and orders import statements. A linter reports patterns that may indicate errors or make code harder to maintain, such as unused imports or questionable constructs.

Formatting does not prove code is correct, and linting does not replace tests, type checking, security analysis, or code review. Treat them as complementary checks rather than interchangeable guarantees.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Tool Primary role Can modify files? Typical command
Black Python formatting Yes black .
isort Import sorting Yes isort .
Ruff Linting, fixes, formatting, and import sorting Yes, when asked ruff check .

Choose a workflow before configuring tools

Use Black, isort, and Ruff together when a repository already depends on their output, an organization requires them, or the project uses isort-specific conventions. Choose Ruff for all three roles when starting fresh or when consolidating tools is valuable and its behavior fits the project.

Consideration Black + isort + Ruff Ruff-only
Existing project stability Smallest change for a repository already using the tools May require an intentional migration and formatting diff
Configuration Settings live across several tool sections Most settings can live in Ruff configuration
Import conventions Retains isort behavior and custom sections Near-equivalent to common isort Black-profile use, but edge cases need checking
Tool separation Each tool has a narrower, explicit role One tool handles multiple roles
Other analysis Can use additional specialized tools Does not eliminate every type checker, security scanner, or project-specific plugin

Ruff describes its formatter as a Black-compatible replacement and its linter as a fast alternative to Flake8 and many related plugins. Those are design goals, not a promise of identical output or universal coverage. See Ruff’s formatter documentation and linter documentation.

Option 1: Keep Black, isort, and Ruff

This setup keeps formatting and import sorting in their established tools while Ruff handles lint diagnostics. Black’s documentation inspected on August 18, 2026, identifies version 26.5.1 and a default line length of 88 characters; that is a documentation snapshot, not a claim that this is the latest release. Black reads settings from [tool.black] in pyproject.toml. Explicit target versions help when Python compatibility matters. See Black’s configuration and usage guide.

[tool.black]
line-length = 88
target-version = ["py311", "py312", "py313"]

[tool.isort]
profile = "black"
line_length = 88
known_first_party = ["my_package"]

[tool.ruff]
line-length = 88
target-version = "py311"

[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP"]
ignore = ["E501"]

[tool.ruff.lint.isort]
known-first-party = ["my_package"]

Replace my_package with the import name Ruff should treat as first-party. The Ruff I rules overlap with isort. In this three-tool example, isort is the import-ordering tool; disable Ruff’s I rules if you do not want Ruff also diagnosing or fixing import order. Keeping them enabled can be useful for checks or fixes, but avoid competing automatic import rewrites unless you have tested the result.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The example uses a compact Ruff baseline: E and F for common style and correctness diagnostics, I for import rules, B for bugbear rules, and UP for modernization suggestions. Add rule families only when their value and remediation cost are understood. Ruff configuration and supported tables can vary by pinned version; consult Ruff’s configuration reference.

Run local checks in a stable order

isort .
black .
ruff check .

Import sorting runs before Black so the formatter gets the final say on layout. To see changes without writing files, use isort --diff . and black --diff .. To verify instead of modifying, run isort --check-only . and black --check .. Black exits with status 0 if files are formatted, 1 if formatting is needed, and 123 for an internal error, which makes --check suitable for CI.

Option 2: Use Ruff for linting, formatting, and imports

For a new project or a deliberate consolidation, Ruff can own all three tasks. Its documented defaults include an 88-character line length, four-space indentation, double quotes, and honoring magic trailing commas; spelling out important choices makes the project’s intent easier to see.

[tool.ruff]
line-length = 88
target-version = "py311"
extend-exclude = ["generated/", "vendor/"]

[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP"]
ignore = ["E501"]

[tool.ruff.lint.isort]
known-first-party = ["my_package"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
line-ending = "auto"
skip-magic-trailing-comma = false
ruff check --fix .
ruff format .
ruff check .

ruff check --fix applies enabled lint fixes; ruff format writes formatting changes. In CI, check without rewriting:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
ruff format --check .
ruff check .

Do not run Black and ruff format as competing formatters on the same files without an intentional, tested reason. Likewise, decide whether Ruff or isort owns import sorting. Ruff’s import sorting is intended to be close to isort with profile = "black", but documented differences include some aliased imports, inline comments, and module classification. See the Ruff FAQ and isort’s Black compatibility guide.

Make line length and formatter rules agree

Matching the configured line length does not mean every long line will be wrapped. Black and Ruff’s formatter make a best-effort attempt to honor the limit, while Ruff’s E501 lint rule can still report long comments or other lines that the formatter leaves unchanged. If that is not your policy, ignore E501; if it is, keep the rule and handle the remaining lines deliberately.

Avoid enabling lint rules that demand a style contrary to the formatter’s choices. Ruff documents potential conflicts involving tab and indentation rules (W191, E111, E114, E117), docstring formatting rules (D203, D206, D300), and quote rules (Q000–Q003). The formatter should own mechanical style choices; lint rules should focus on diagnostics the formatter cannot resolve. Details are in Ruff’s formatter guidance.

Install and pin the tools your team runs

Install tools into the project’s development environment rather than relying on a global machine setup:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
python -m pip install black isort ruff

For Ruff-only, install ruff instead. Declare the chosen tools in the project’s environment or packaging workflow, and pin or constrain versions that have been tested—especially in CI and pre-commit. Do not infer a tool’s latest version from another tool’s documentation. Check the installed versions with:

ruff --version
black --version
isort --version-number

Automate local checks with pre-commit

pre-commit runs configured hooks in isolated environments, so contributors can use the same checks without separately managing every hook installation. A traditional hook setup can pin the inspected isort and Black revisions and enable Ruff linting:

repos:
  - repo: https://github.com/pycqa/isort
    rev: 6.0.1
    hooks:
      - id: isort
        args: ["--profile", "black"]

  - repo: https://github.com/psf/black
    rev: 26.5.1
    hooks:
      - id: black

  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: <tested Ruff release tag>
    hooks:
      - id: ruff
        args: [--fix]

Replace the Ruff revision with a tested release tag before using the configuration. For Ruff-only, use the Ruff hook repository with ruff-check and ruff-format hooks instead of separate Black and isort hooks; pin its revision to the version tested by the project. Put a fixing lint hook before the formatter, since fixes can change code that then needs formatting. See Ruff’s integration guide and pre-commit documentation.

pre-commit install
pre-commit run --all-files

Use pre-commit autoupdate intentionally to propose hook revision updates, then review and test those updates rather than letting local and CI versions drift.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Enforce the same checks in CI

CI should normally validate rather than silently rewrite a pull request. For GitHub Actions, a Ruff-only job can run formatting and lint checks after installing the pinned project dependency:

name: Quality

on:
  push:
  pull_request:

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - run: python -m pip install --upgrade pip
      - run: python -m pip install ruff
      - run: ruff format --check .
      - run: ruff check .

For the traditional stack, the validation commands are:

isort --check-only .
black --check .
ruff check .

Install exact tested versions in the workflow rather than relying on an unconstrained installation if reproducibility matters. Ruff’s official integration examples also document its GitHub Action and output suitable for GitHub annotations.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Migrate an existing Black and isort project carefully

A formatter migration is easiest to review when separated from behavior changes. Use a branch, record the current tool versions, and make sure the existing checks and tests pass before comparing output.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Choose a trial branch. Keep the current checks available while trying Ruff; decide whether you are replacing only linting, import sorting too, or the formatter as well.
  2. Compare import behavior. For a Ruff import-sort trial, run ruff check --select I --fix . and inspect changes to aliased imports, inline comments, custom first-party sections, and generated files.
  3. Compare formatter output. Run ruff format ., then inspect the diff against the project’s existing Black-formatted state. Ruff’s Black-compatible goal does not guarantee identical output in every historical, preview, notebook, or unusual-syntax case.
  4. Check exclusions and notebooks. Verify generated and vendored paths, notebook cell magics, Markdown code blocks, metadata preservation, and whether notebooks belong in CI formatting checks.
  5. Separate the rewrite. Put formatting-only changes in a dedicated commit, pin the selected versions, and update editor, pre-commit, and CI commands together.
  6. Run the full project checks. Test after enabling lint fixes, particularly if broader rule families can suggest semantic changes. Keep the old workflow available until the new checks are accepted.

If you want Ruff linting but must retain Black, a hybrid can use Ruff for diagnostics and import rules while Black remains the formatter. Test Ruff’s I behavior against the repository before removing isort; it is not automatically the right choice for custom import conventions.

Troubleshoot the common conflicts

Imports change every time tools run

This usually means more than one tool is rewriting imports or they disagree on configuration. In the traditional stack, use isort . followed by black ., inspect git diff, and decide whether Ruff should diagnose import order or whether isort alone owns it. For a Ruff-centered setup, remove separate import-sorting hooks unless a tested requirement justifies both.

Formatting passes but Ruff reports line length

Check whether E501 is enabled. The formatter may leave a long comment or similar line intact. Either keep the rule and shorten those lines manually, or make the policy choice to ignore E501 in Ruff configuration.

Lint fixes are followed by another formatter diff

Run fixes before formatting, then validate again: ruff check --fix ., followed by ruff format . and ruff check .. If using Black, keep it as the final formatting authority after any code-changing lint fixes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The migration diff is too large to review

Make the formatter change a dedicated commit, exclude generated paths, pin the formatter version, and avoid mixing behavior changes into the same review. Review any generated files separately.

Local results differ from CI

Compare installed tool versions, configuration roots, and commands. Pin versions in development dependencies, pre-commit revisions, and CI installation so developers and automation run the same checks.

What Ruff does not replace

Ruff can replace many common linting, formatting, and import-sorting tasks, but it is not a universal substitute for every plugin or analysis category. Type checking, security analysis, dependency auditing, tests, and architecture-specific rules may need separate tools. More enabled rules are not automatically better: a small, explainable baseline tends to be easier to maintain than a large set that generates noise or routine suppressions.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.