mrkeyoor.com_
Sat 26 Sept 18:46 UTC
Dev Toolsevaluationupdated 25 Aug 2026

ruff review

Ruff is a Python linter and formatter written in Rust. It combines style checks, import sorting, code upgrades, and formatting in one executable, reducing the number of tools a Python project must configure.

+82stars / 7d
Verdict

Most modern Python projects should try Ruff, starting with linting and adding its formatter if the documented differences are acceptable. It can replace a surprising amount of routine tooling, but it should sit beside a type checker and any unsupported specialist checks. Pin the version, review the first large fix or format diff, and keep the old tools until coverage matches.

We ran it

Lab card: what happened when we ran ruffScreenshot of ruff (docs.astral.sh/ruff)
Install✓ · 407s36 packages · 61 MB
Build✗ · 15s
Testsn/ano test script
Known vulns0(pip-audit)
Repo10299 files~917,461 lines of source · 81.7 MB · 20 CI workflows · Dockerfile

Answers from our run

Does ruff build from source?

Dependencies installed in 407 seconds (36 packages), and the build failed. We cloned commit 423b9fb into a clean Debian container with 3 CPUs and no project-specific setup.

Does ruff have tests you can run?

Not through a standard command: the project exposes no test script or target that our harness could run.

Does ruff have known vulnerabilities in its dependencies?

pip-audit found none in the dependency tree at the time of our run.

Who should not use ruff?

Teams dependent on private or third-party Flake8 or Pylint plugins: Ruff cannot load custom lint plugins and ships its rules inside the binary.

What are the alternatives to ruff?

Flake8, Black, Pylint. Most modern Python projects should try Ruff, starting with linting and adding its formatter if the documented differences are acceptable.

Setup5/5Published binary is easy; source development is a different job
Docs5/5Excellent rule, setting, migration, editor, and behavior references
Community5/5Same-day code activity and frequent releases across a large queue
Maturity5/5Widely used with a clear, still pre-1.0 version policy

Discussed on

  1. hnRuff: Python linter and code formatter written in Rust200 points
  2. hnAvoid unnecessary parser lookahead for operators3 points
  3. hnRuff: fast Python linter and code formatter, written in Rust3 points

Who it’s for

Python teams that want one fast tool for linting, import sorting, and formatting.
Large repositories where slow hooks discourage developers from running checks locally.
Projects using Flake8 plugins, Black, isort, pyupgrade, or autoflake behavior that Ruff already implements.
Monorepos that need cascading configuration across editor, pre-commit, and CI use.

Who it’s NOT for

Teams dependent on private or third-party Flake8 or Pylint plugins: Ruff cannot load custom lint plugins and ships its rules inside the binary.
Python 2 codebases: the FAQ explicitly says Python 2 is unsupported.
Projects expecting Ruff to replace a type checker or every Pylint check: its docs say type errors and some inference-based findings remain outside its scope.
Repositories requiring byte-for-byte Black or isort output: Ruff documents intentional formatter and import-sorting differences.
Organizations unwilling to pin and test upgrades: Ruff remains below 1.0, and its version policy permits some breaking changes in minor releases.

Setup reality

Our fresh sandbox installed 36 packages in 407 seconds and used 61 MB. The build failed after 15 seconds with exit code 1. Its log tail contains SyntaxWarning messages from parser fixtures and a generated jemalloc test script, but it never shows the final build error, so those warnings cannot be named as the cause. No test script or target was found, and tests were skipped. Pip-audit found 0 known vulnerabilities.

Installing the published Ruff binary is much simpler than building this Rust repository. Users can run it through uv, pip, pipx, Homebrew, Conda, or a standalone installer. Source contributors need the repository's Rust development path.

Migration still takes care: map Flake8 plugins, Black and isort choices, per-file ignores, target versions, editor settings, and CI hooks. Run it in reporting mode first, inspect fixes and formatting, then pin the chosen release.

One executable for the repetitive parts of Python quality

Ruff combines linting, formatting, import sorting, and many automatic code upgrades in a Rust executable. Its rule catalog includes native implementations of behavior associated with popular Flake8 plugins, pyupgrade, pydocstyle, autoflake, and isort. The formatter aims for close compatibility with Black. For many projects, that means fewer development dependencies, fewer configuration files, and one command that behaves the same in an editor, a commit hook, and CI.

Speed is the product's defining advantage. Astral says Ruff runs much faster than the Python tools it replaces and includes a cache to avoid rechecking unchanged files. Those are the project's claims, not measurements from our sandbox. The practical value is believable without repeating a benchmark: checks that return quickly are easier to run on every save and commit. A team still needs to decide which rules are useful. Fast feedback does not make an unsuitable rule correct for a codebase.

What happened when we ran it

We cloned commit 423b9fb into a fresh unprivileged Python 3.12 Bookworm container with three CPUs, 8 GB of memory, and no secrets. The repository contained 10,299 files and about 917,461 lines of source. Installation succeeded in 407 seconds, bringing in 36 packages and using 61 MB on disk. Pip-audit reported 0 known vulnerabilities.

The build ran for 15 seconds and exited 1. The available tail shows SyntaxWarning messages from deliberately odd Python parser fixtures, including invalid escape sequences and expressions that index or call an integer. It also ends on a warning inside a generated jemalloc test script. The tail never displays the final build error. It therefore does not establish whether those warnings caused the exit, and assigning the failure to fixtures, a compiler, or a dependency would be guesswork.

Our harness found no test script or target and skipped tests. That is not a passing test result. Ruff has 20 CI workflow files, but the generic repository run did not discover the contributor test entry point. Anyone changing the Rust source should follow the contributing guide and run its named checks rather than treating this root result as approval.

Using Ruff is easier than building Ruff

The published tool installs through uv, pip, pipx, Homebrew, Conda, standalone scripts, and other package managers. Common platforms receive prebuilt binaries, so a Python developer does not need Rust. ruff check handles linting and ruff format handles formatting. The two can be adopted independently: keep Black while introducing the linter, or use Ruff's formatter while enabling only a conservative set of rules.

Defaults cover common errors and avoid stylistic lint rules that conflict with a formatter. Configuration lives in pyproject.toml, ruff.toml, or .ruff.toml. Monorepos can use hierarchical discovery and cascading files. Ruff also documents pre-commit, GitHub Actions, notebooks, VS Code, and other editors. This breadth turns a local trial into a short exercise rather than a tooling project.

Automatic fixes deserve a staged rollout. Ruff distinguishes safe and unsafe fixes, requiring an explicit choice for the latter. Begin by reporting findings, enable fixes in a reviewable branch, and inspect the full diff. On an established codebase, the first formatting pass should be its own change so later feature work is not buried in mechanical edits.

Consolidation has firm boundaries

Ruff cannot load arbitrary third-party Flake8 rules. A company with an internal checker must keep Flake8, upstream equivalent behavior, or enforce that policy another way. Pylint's plugin system and inference-based checks also extend beyond Ruff's stated scope. Consolidating overlapping style and upgrade tools is realistic; replacing every kind of Python analysis is not.

A type checker remains necessary. Ruff can flag suspicious syntax and unused names, but it does not generally prove that values match declared types across a program. Mypy, Pyright, or another type checker still has a separate job. Legacy teams face a harder boundary because Ruff does not support Python 2.

Formatter compatibility is close rather than exact. Ruff documents deliberate differences from Black around some comments, f-string expressions, multiline strings, and nested expressions. Import sorting likewise differs from isort in certain alias, comment, and configuration cases. These differences are reasonable engineering choices, but a repository that treats formatting as generated output should compare the old and new results before removing Black or isort.

Preview mode also needs restraint. It enables unstable rules, fixes, formatter behavior, and interfaces that may change before stabilization. Use it to evaluate upcoming behavior on a branch, not as an automatic setting across production repositories.

Health and the buying decision

Ruff remains below 1.0 and publishes a specific versioning policy. Minor releases may contain breaking changes to configuration, stable rules, formatting, supported file types, or the language server. Patch releases are intended mainly for fixes and compatible additions. Exact version pins in pre-commit and CI make upgrades reviewable and keep every developer on the same behavior.

The repository was pushed on August 25, 2026. Release 0.16.4 arrived on August 20 with fixes for a Windows CPU instruction issue, changes to lint and syntax rules, and language-server work. GitHub reported 2,156 open issues and pull requests combined. That is a large public queue, but the current release and same-day push show active maintenance.

Ruff is the default trial for a new Python project and a strong migration candidate for an old one. Keep the limits visible: it is not a type checker, it cannot run private lint plugins, and its formatting is not identical to every predecessor. If those boundaries fit, the smaller toolchain and quicker local feedback justify the migration work.

Alternatives

ProjectWhat it isPick it when
Flake8The established Python lint runner with a large third-party plugin ecosystem.pick this instead when custom or unsupported Flake8 plugins are required.
Black gh↗The widely adopted opinionated Python formatter whose style Ruff follows closely.pick this instead when exact Black output and Black's own release policy matter more than consolidating tools.
PylintA deeper Python analyzer with inference-based checks and a plugin system.pick this instead when semantic checks or custom checkers matter more than execution speed.

What people are saying

  1. [github-trending] astral-sh/ruff

Sources

  1. Ruff README
  2. Ruff FAQ
  3. Known deviations from Black
  4. Ruff versioning policy
  5. Ruff 0.16.4 release

More dev tools reviews

terminal-browser · fearless_simd · devops-exercises · scriptc · 30-seconds-of-code · styleguide · the whole board →

Related reading