Should You Replace Black with Ruff?
Ruff has overtaken Black in monthly downloads and runs 30x faster. Here is when to switch and when to stay.

Ruff has overtaken Black in monthly downloads and runs 30x faster. Here is when to switch and when to stay.

Ruff has overtaken Black in monthly PyPI downloads (≈180M vs ≈134.9M as of April 2026) and runs 30x faster as a formatter. One governance caveat every SERP comparison misses: OpenAI acquired Astral, Ruff's creator, in March 2026.
For new Python projects, Ruff is the clear choice: it replaces Black plus Flake8, isort, pyupgrade, and autoflake in one binary with >99.9% formatting compatibility. Black is the better call when PSF community governance is a hard requirement or when migrating a stable legacy codebase is more trouble than it's worth.
Feature | Ruff | Black |
|---|---|---|
Best For | New projects, multi-tool replacement | Legacy codebases, PSF governance |
Language | Rust | Python |
Speed (formatting) | 30x faster than Black | Baseline |
Scope | Formatter + linter + import sorter + upgrader | Formatter only |
Black Compatibility | >99.9% (4 intentional deviations) | N/A |
License | MIT (OpenAI-owned via Astral acquisition) | MIT (Python Software Foundation) |
Latest Release | v0.15.19 (June 24, 2026) | v26.5.1 (May 18, 2026) |
Monthly PyPI Downloads | ≈180M (April 2026) | ≈134.9M |
GitHub Stars | 48,143 | 41,578 |
Primary Config Section |
|
|

Ruff is a Python linter and formatter written in Rust, created by Charlie Marsh at Astral in August 2022. The formatter launched in beta in October 2023 and became stable with v0.3.0 in 2024. In March 2026, OpenAI acquired Astral, absorbing Ruff, uv, and ty into OpenAI's Codex division; the MIT license is retained.
Ruff's value proposition is scope. ruff format handles Black-compatible formatting. ruff check covers linting with 900+ rules (Flake8's full rule set plus bugbear and dozens of plugin extensions). Import sorting replaces isort; code upgrades replace pyupgrade and autoflake. One binary, one config file, one CI step.
ruff format after Black on the TensorFlow codebase still reformatted 588 files, confirming stylistic differences at scaleruff check --fix before ruff format or an explicit ignore = ["COM812"] in your config
Black is an opinionated Python code formatter created by Łukasz Langa in 2018 and transferred to the Python Software Foundation in 2021. Black's positioning is "the uncompromising Python code formatter": you accept its decisions, and in return you stop arguing about style. It has been the community standard for Python formatting since roughly 2019.
Black uses CalVer versioning (v26.5.1 released May 18, 2026). Development posture is maintenance mode: the PSF ensures continued, stable development, but Black is not racing to add features. It's formatter-only by design.
uv + ruff + pyright with no mention of Black; GitHub stars (41,578) and monthly downloads (134.9M) now trail Ruff on both metricsSpeed is Ruff's clearest advantage. Ruff is written in Rust; Black is written in Python.
On Astral's official Zulip benchmark: Ruff formats in 0.10 seconds, Black in 3.20 seconds, a 30x speedup. On large codebases, formatting jobs that take minutes in Black complete in under a second with Ruff.
The speedup extends to linting: Ruff lints CPython in ~0.3 seconds vs Flake8's ~12 seconds (40x faster).
Tim Abbott, Zulip lead developer: "This is just ridiculously fast... ruff is amazing."
One more data point worth knowing: with caching disabled, Ruff still outperforms Black with caching enabled. In real monorepo migrations, pre-commit stages drop from tens of seconds to well under a second.
Winner: Ruff. The performance gap holds across all published benchmarks and real-world migrations.
For teams migrating from Black, the practical question is whether Ruff will introduce formatting churn on an existing codebase.
Ruff's formatter was explicitly designed as a Black drop-in. Astral documents four intentional deviations:
Deviation | Black behavior | Ruff behavior |
|---|---|---|
Trailing EOL comments | May re-flow lines with trailing comments | Expands any statement containing trailing EOL comments |
Pragma comments ( | Avoids splitting | Ignores pragma comments when computing line width; avoids moving them |
Unicode line-width | Unicode width for strings; character width for other tokens | Unicode width consistently for all tokens |
Long nested-expression parenthesizing | PSF algorithm (Black 24+) | Prettier-style algorithm |
On Django's codebase, only 34 of 2,772 files differ between Black and Ruff output. On a first ruff format run of a Black-formatted repo, expect ~0.1% of files to change. The changes are cosmetic; no semantic differences.
The pragma comment deviation is the one to watch on codebases that rely heavily on inline # noqa suppressions. Black can unintentionally broaden # noqa scope by collapsing lines; Ruff's handling is safer.
Winner: Tie for most codebases. Ruff's >99.9% compatibility holds at real-world scale. For teams with strict byte-identical requirements, Black wins by definition.
Practitioners who frame this as a formatter-to-formatter swap are missing the bigger picture. Switching to Ruff means eliminating four other tools alongside Black, not just upgrading a formatter.
Black is a formatter only. A standard Python project using Black also needs:
Ruff covers all of these in one binary. Formatting maps to ruff format; linting to ruff check with 900+ rules (Flake8's full set plus bugbear extensions). Import sorting uses the I rule group, code upgrading the UP group, docstring checks the D group, and unused-import removal F401 auto-fix.
Sebastián Ramírez (@tiangolo), FastAPI's creator, described the moment FastAPI switched from Black to Ruff in October 2023:
So, @FastAPI now uses the Ruff formatter. 😎✨ Ruff alone is now replacing (for me): * flake8 * autoflake * isort * pyupgrade * black ...and Ruff is still crazy fast. 🚀 I keep intentionally adding broken code just to ensure it is indeed running. 🤪
Charlie Marsh announced Pytest's migration three months later:
Pytest moves to Ruff! 🚀🚀🚀 Replaces autoflake, black, isort, pyupgrade, flake8, and pydocstyle... https://t.co/7JLfsOrWmR
Corey Schafer (95k-view Ruff tutorial): "I've actually switched over to using it as my main linter and formatter for Python, which has allowed me to replace a few other tools with just this one."
On r/Python, the pattern is now the default in new projects. As u/JaffaB0y in r/Python (May 2025) asked: "why use black when you're using ruff for lint and it's got format builtin?"
Winner: Ruff. When scope matters, Ruff wins. For teams who want a formatter and nothing else, Black is cleanly scoped.
Here is the pyproject.toml translation from Black to Ruff, based on Ruff's official migration guide:
Current Black config:
[tool.black]
line-length = 88
target-version = ["py39"] # list
skip-string-normalization = true
extend-exclude = ''' # regex
/(migrations|vendor)/
'''Ruff equivalent:
[tool.ruff]
line-length = 88
target-version = "py39" # string, not a list
[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B"]
[tool.ruff.format]
quote-style = "preserve" # = skip-string-normalization
magic-trailing-comma = "respect" # "ignore" = skip-magic-trailing-commaKey-by-key translation table:
Black key | Ruff equivalent | Gotcha |
|---|---|---|
|
| Identical |
|
| String in Ruff, not a list |
|
| Section changes |
|
| Section changes |
|
| Syntax changes |
Full migration steps:
pip install ruff or uv add --dev ruff[tool.black] using the table abovepip uninstall black flake8 isort pyupgrade autoflakeruff check --fix . then ruff format .; this order matters (lint fixes first, then format)- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.19
hooks:
- id: ruff-check
args: [--fix]
- id: ruff-formatpsf/black@stable and PyCQA/flake8 actions with:- uses: astral-sh/ruff-action@v4
with:
args: "check --fix"
- uses: astral-sh/ruff-action@v4
with:
args: "format --check"Run order matters: ruff check --fix before ruff format. Running in reverse causes the formatter to write code the linter then flags, most visibly on the COM812 trailing-comma rule. Either fix the run order in pre-commit or add ignore = ["COM812"] to [tool.ruff.lint].
Winner: Tie. Black's single-tool config has less surface area to manage. Ruff's migration is a one-time cost with a five-tool reduction as the payoff.
The governance contrast between Ruff and Black in 2026 is the sharpest in Python tooling history, and it's absent from every comparison article currently ranking on Google.
Ruff: Created at Astral with VC backing. In March 2026, OpenAI acquired Astral, absorbing Ruff, uv, and ty into the OpenAI Codex division with Charlie Marsh. The MIT license is retained, and OpenAI has publicly committed to open-source tooling, though the organizational concentration is real.
Black: Created by Łukasz Langa (CPython core developer, Python 3.8/3.9 Release Manager) in 2018 and transferred to the Python Software Foundation in 2021. No corporate owner, no VC: governed by the nonprofit steward of the Python language.
The community response to the OpenAI acquisition was measured but concerned. u/latkde in r/Python (April 2026): "Astral's business model always seemed unclear, and an acquihire is a relatively unsurprising outcome. We've all built on Astral tooling knowing that it was unsustainable. But having the fate of these tools chained to what may be the biggest bubble in tech economy history doesn't exactly soothe my worries."
The community's answer to concentration risk is the MIT license. u/menge101 in r/Python (April 2026): "Keep in mind, ruff and ty are MIT licensed. UV is apache2 and MIT licensed. We can fork these things if needed to stop from being trapped into anything by OpenAI."
There's also a legitimate ethics objection that predates the acquisition. Anthony Sottile, maintainer of pyupgrade and other tools Ruff reimplemented, named it in his YouTube critique:
"Ruff kind of kills a lot of projects that I was working on, and I don't really feel incentivized to contribute to this space anymore, especially when someone is profiting off my work and the work of others in the community."
The OpenAI acquisition makes that observation more pointed, not less.
Winner: Black. If PSF governance or corporate-ownership concerns apply to your team's policy, Black is the structurally safe pick and is likely to stay that way.
By raw numbers, Ruff has crossed a threshold Black held for years.
Metric | Ruff | Black |
|---|---|---|
Monthly PyPI downloads | ≈180M (April 2026) | ≈134.9M |
GitHub stars | 48,143 | 41,578 |
GitHub releases | 415 | 55 |
Release cadence vs Black | ~7.5x faster | Baseline |
Major adopters | FastAPI, Pandas, Hugging Face, Apache Airflow, SciPy, Pydantic | Deep lock-in across millions of legacy repos |
Nick Schrock, co-creator of GraphQL: "Why is Ruff a gamechanger? Primarily because it is nearly 1000x faster. Literally, not a typo."
Timothy Crosley, creator of isort (which Ruff replaces): "Just switched my first project to Ruff. Only one downside so far: it's so fast I couldn't believe it was working till I intentionally introduced some errors."
u/Khavel_dev in r/Python (May 2026): "uv and ruff are the obvious ones but they genuinely changed the daily experience for me. Before uv I'd wait 30+ seconds to create an env and install deps. Now it's basically instant for most projects."
Google Trends shows ruff python outpacing black formatter by 1.5x–3x consistently, with Ruff peaking at index 100 in March 2026, coinciding with the Astral acquisition announcement and a surge in community discussion. Modern Python project templates on r/Python (2025–2026) list uv + ruff + basedpyright with Black absent.
Winner: Ruff. Black maintains a larger installed base in legacy codebases, but new projects are defaulting to Ruff.
Both Ruff and Black are free and MIT-licensed. The real cost difference is toolchain overhead.
Black stack:
pip install black flake8 isort pyupgrade autoflake (five separate packages to install, pin, and update)[tool.X] config sections to maintain in pyproject.tomlRuff stack:
pip install ruff (one package)[tool.ruff] config section (plus [tool.ruff.format] and [tool.ruff.lint] subsections)ruff-check, ruff-format)No licensing cost for either tool. The real cost comparison is maintenance overhead and CI time, both of which favor Ruff on anything beyond a small solo project.
Choose Ruff if you're starting a new Python project, care about CI speed, want to consolidate five tools into one, or are comfortable with OpenAI's stewardship of an MIT-licensed codebase. For the vast majority of Python teams in 2026, this is the right call.
Choose Black if PSF community governance is a hard requirement or your organization has a policy against AI-company-owned tooling. It's also the right call on a stable legacy codebase where a ~0.1% formatting diff and migration effort aren't worth the speed payoff.
The community default has shifted. Ruff has overtaken Black in downloads, dominates new-project templates, and offers a meaningfully larger scope for the same zero-dollar price. If you're starting a new repo or auditing your toolchain, Ruff is the move; if you're already on Black and everything works, staying put is reasonable, with the PSF ensuring stable maintenance.

uv replaces pip, pyenv, virtualenv, pip-tools, and pipx with one Rust binary. Complete guide to installation, commands, Docker integration, and migration paths.

LangChain wins for stateful multi-agent orchestration and the broadest integration surface. LlamaIndex wins when retrieval accuracy over private documents is th

Playwright wins for new Python projects in 2026. It runs 44% faster than Selenium on React SPAs, eliminates flaky waits with built-in auto-waiting, and ships bo