Skip to content
Latchkey

Flake8 vs Ruff: The Python Linting Shift

Ruff reimplements most Flake8 checks in Rust and runs vastly faster; Flake8 keeps a long tail of plugins and familiarity.

Flake8 has been the default Python linter, gluing pyflakes, pycodestyle, and a plugin ecosystem together. Ruff covers many of those same rules at much higher speed with a single binary and one config.

Flake8Ruff
LanguagePythonRust
SpeedSlow on large reposVery fast
PluginsLarge ecosystemMany rules built in, fewer external plugins
Configsetup.cfg / .flake8 / tox.inipyproject.toml [tool.ruff]
AutofixNoYes for many rules

Where Ruff wins

Ruff is far faster, autofixes many issues, and consolidates several tools behind one config. It maps Flake8 rule codes, so migration is often a matter of enabling the equivalent rule sets. For most codebases it covers the checks you actually use.

Where Flake8 wins

Flake8 has a large, mature plugin ecosystem. If you depend on a niche Flake8 plugin that Ruff has not yet reimplemented, Flake8 still has the broader long tail. Some teams also value its long, stable track record.

Migration

Move Flake8 config into [tool.ruff], enable the matching rule families, and compare output on your codebase before switching the CI gate. Keep a specific Flake8 plugin only if Ruff lacks an equivalent.

The verdict

For most projects Ruff is the better default now: faster, autofixing, single config. Stay on Flake8 (or run it alongside) only for plugins Ruff has not yet covered.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →