Ruff puts linting and formatting behind separate commands
Replace an unused-import check first, and Ruff's appeal becomes concrete: ruff check reports problems, while ruff format handles layout. The project README describes native replacements for familiar Flake8 plugins, import sorting, and Black-style formatting. You can adopt the linter while keeping your formatter. That makes Ruff a sensible choice when a Python repository has accumulated overlapping tools and you want fewer configurations to explain to the next contributor.
Our checkout contained 10,452 files and roughly 973,673 lines of source, occupying 86 MB. That is the tool's development repository, a much larger object than the command you add to an application's checks. The README's speed claims do not become our benchmarks by appearing here. We measured repository setup and a failed build, so this recommendation rests on the documented consolidation and configuration model, with that verification limit kept visible.
What happened when we ran it
Our Ruff sandbox installed commit 9520164 in 482 seconds, adding 36 packages and occupying 62 MB on disk. The October 9, 2026 run used 3 CPUs and 8 GB of RAM in an unprivileged Debian container based on ghcr.io/astral-sh/uv:python3.12-bookworm. Installation succeeded. The build then failed with exit code 1 after 3 seconds, and the harness skipped tests because it found no supported test script or target.
The failing log tail shows Python SyntaxWarnings in parser resources, including invalid escapes in f_string.py and expressions such as 100[no] and 100(no) in number_literal.py. It also shows an invalid-escape warning in a generated jemalloc helper. Those lines do not identify the fatal error. Blaming Rust, a missing system package, or the parser would go beyond the supplied evidence. We have a failed step and an incomplete explanation.
Pip-audit reported 0 known vulnerabilities for the scanned environment. The repository scan found 23 CI workflow files and a Dockerfile, but no tests directory. That directory signal does not establish that upstream has no tests, and our skipped step proves no passing suite. The audit also does not cover every possible defect in a Rust tool. Treat these as narrow observations from this sandbox, rather than a certification of the published executable.
Custom Flake8 plugins cannot move across unchanged
Ruff's FAQ on tool compatibility says custom and third-party lint plugins are unsupported. Its built-in rules are implemented by the project itself. If your team wrote a Flake8 plugin that checks internal API conventions, keeping Flake8 may be the better decision even when Ruff covers the ordinary checks. Count the rules you actually depend on before removing an existing tool. A large catalog cannot substitute for one missing company-specific check.
The 36 packages in our sandbox say nothing about whether your current rule policy survives migration. Pylint also performs inference that Ruff does not duplicate, including checking argument counts in some calls. Ruff is not a type checker either. Keep the tool responsible for the checks you still need, and compare diagnostics on representative files before switching your CI requirement. Consolidation earns its place only if useful warnings survive it.
Version 0.17.0 changes defaults and drops the old language server
Release 0.17.0, published October 9, changes the default target to Python 3.11 when no version is configured. It also changes the default rule set and removes support for the legacy ruff-lsp server. These are practical upgrade costs: a pinned project with explicit settings is easier to reason about than a workstation following the newest release and inheriting defaults. Existing editor integrations deserve a compatibility check.
For an application team, the README documents packaged tools and standalone binaries rather than requiring a source checkout. Our 482-second installation does not predict the duration of those routes. No hosted account or API secret is needed for local linting. Put the intended Python target and selected rules in pyproject.toml, ruff.toml, or .ruff.toml, and keep preview mode an explicit choice. The README labels preview features unstable, so enabling them adds another source of changing output.
Formatting similarity still calls for a reviewed diff
The formatter documentation describes a Black-compatible style with intentional differences. That is enough reason to review a formatting-only change separately from edits to application behavior. Ruff also documents differences from isort around aliased imports and comments. If exact Black output or an unsupported isort setting is part of your repository contract, retaining that tool can cost less than negotiating a new convention across every contributor.
Our 3-second build failure leaves source-development confidence unresolved, but it doesn't answer the formatting-policy question. Compare an actual diff on your own code. Begin with checks, then review automatic fixes before letting them rewrite a large repository. The current release distinguishes displayed unsafe suggestions from applying them: application still requires explicit opt-in. That distinction matters when a seemingly cosmetic tool can also delete or transform code.
October activity supports adoption with pinned settings
The repository was pushed on October 10, 2026, and GitHub listed 49,975 stars with 2,219 open issues and PRs. Recent activity included a Ruff-specific rule proposal about block/local variable overlap and an updated request to generalize type-alias checks. Some adjacent activity concerns Astral's ty work, so the queue should not be read as thousands of Ruff bugs. The release and relevant issue activity together show ongoing maintenance, without promising a response to your particular request.
Choose Black if stable formatting conventions are the main requirement, or Flake8 if your own plugin must remain loadable. Ruff is my preferred candidate for combining ordinary Python linting and formatting behind explicit, pinned settings. A team maintaining Ruff itself has a different decision: our 86 MB checkout installed successfully but did not build successfully. For an application migration, keep the first change small enough that you can explain every removed check and every rewritten line.

