Python tooling that is fast enough to disappear
Ruff combines a Python linter, formatter, import sorter, and a large catalog of automatic code upgrades in one Rust executable. The project says it implements more than 900 lint rules, including native versions of many popular Flake8 plugins and behavior associated with pyupgrade, pydocstyle, autoflake, and isort. The formatter aims for close compatibility with Black.
The speed claim is central, not decorative. Astral reports Ruff running 10 to 100 times faster than existing Python linters and formatters, with larger improvements in some user reports. Those are project and user measurements rather than a guarantee for every repository. The practical benefit is still easy to understand: a check that returns almost immediately can run in an editor, on every commit, and in CI without becoming the step developers learn to avoid. Built-in caching reduces repeat work further.
The first run is unusually easy
Ruff installs through uv, pip, pipx, Homebrew, Conda, standalone scripts, and other package managers. Common platforms receive prebuilt binaries, so Python users do not need a Rust toolchain. ruff check lints a directory, while ruff format formats it. The two parts are independent, so a team can adopt the linter while keeping Black, or use the formatter without accepting every lint rule.
The defaults are useful without being timid. They catch errors such as unused imports and cover common style, bug-risk, upgrade, and Ruff-specific categories while avoiding stylistic lint rules that fight a formatter. Configuration belongs in pyproject.toml, ruff.toml, or .ruff.toml. Monorepos get hierarchical discovery and cascading configuration, and command-line overrides handle one-off checks. Jupyter notebooks, pre-commit, GitHub Actions, VS Code, and other editors have documented paths.
Automatic fixes deserve a measured rollout. Ruff distinguishes safe fixes from unsafe ones, requiring explicit permission for the latter. That is better than pretending every mechanical rewrite preserves intent. Even safe fixes should first run in a pull request on a mature codebase, particularly when enabling a broad rule family. A fast wrong edit is still wrong.
Consolidation has a boundary
Ruff can replace Flake8 cleanly when a project uses Python 3, Black, and either no plugins or plugins Ruff has reimplemented. It cannot load arbitrary third-party rules. A company with an internal Flake8 checker must retain that runner, upstream the rule, or rewrite its policy around Ruff's built-ins. The same limitation applies to custom Pylint checkers.
Ruff is also not a type checker. Its FAQ recommends using it beside Mypy, Pyright, or Pyre. It can find unused imports and suspicious syntax that a type checker may ignore, but it will not generally prove that an integer was passed where a string was required. Pylint still performs inference-based checks Ruff does not match. Replacing six overlapping style tools is realistic; replacing every form of Python analysis is not.
Legacy projects face another hard stop: Python 2 is unsupported. Ruff targets Python 3 code, and its documentation says old type comments may not be respected. That makes modernization a prerequisite, not a configuration tweak.
Black compatibility is close, not identical
The formatter is designed as a Black replacement and Astral reports more than 99.9 percent identical lines on large projects already formatted by Black. Unformatted code can show more differences, especially around end-of-line comments. Ruff intentionally keeps such comments near their original expressions, ignores pragma comments when measuring line width, formats expressions inside f-strings, and makes different decisions for some nested expressions, multiline strings, and implicit string concatenation.
Import sorting follows a similar pattern. It aims to match isort's Black profile but differs around aliased imports and inline comments, and it does not implement every isort option. These are not reasons to reject Ruff. They are reasons to run both old and new tools against the entire repository before deleting the old configuration. Teams that treat formatting as generated output should expect one reviewed migration diff and then let Ruff own the result.
Preview mode needs restraint. It unlocks unstable rules, fixes, formatter changes, and interfaces, but selecting a preview category can include matching preview rules unless explicit selection is configured. Use it to test upcoming behavior, not as an automatic switch in every production repository.
Versioning and project health
Ruff remains below 1.0 and uses a custom policy: minor versions can contain breaking configuration, stable rule, formatter, file-type, or language-server changes, while patch versions primarily carry fixes and compatible additions. The project says it does not yet have a stable API. Pinning an exact release in pre-commit and CI is therefore sensible, followed by intentional upgrade pull requests.
The maintenance signal is excellent. The repository was pushed on August 12, 2026, five days after release 0.16.2 was published. That patch fixed a false positive and corrected language-server formatting capability registration. Its 2,096 open items combine issues and pull requests, a large queue that reflects both broad scope and intense development. A newly filed nix-shell shebang false positive received a response the same day, while multiple fixes and features were moving through review.
Ruff is mature enough for a default recommendation even with its pre-1.0 label. Adopt it incrementally, preserve specialist tools where the documented boundary demands them, and lock the version. For most Python teams, the simpler configuration and near-instant feedback are worth the small migration cost.