3 Python Linters Compared by Speed and Depth
Compare three Python linters: Ruff, Flake8, and Pylint. Speed, rule coverage, Flake8 drop-in vs Pylint residual, VS Code setup, and when to keep each one.

Compare three Python linters: Ruff, Flake8, and Pylint. Speed, rule coverage, Flake8 drop-in vs Pylint residual, VS Code setup, and when to keep each one.

If you pick one Python linter in 2026, pick Ruff: a Rust binary that lints and formats in milliseconds. Flake8 is the style stack you migrate off when plugins are few; Pylint still wins on inference, duplicate code, and import cycles. Astral's FAQ says Ruff is not a pure replacement for Pylint.
A linter analyzes how code runs; a formatter only rewrites how it looks. Type checkers (mypy vs pyright) catch "int where str expected."
Browser paste toys exist; this roundup covers three CLI tools. Install and config for Ruff live in the Ruff guide.
Ruff is the 2026 default. Flake8 is the stack you migrate from. Pylint covers residual semantic depth.
--check only in CI.Ruff vs Flake8 vs Pylint at a glance

Best for greenfield Python and CI that has to finish in seconds
Ruff is a Rust linter and formatter. It ships 900+ rules that stand in for Flake8 plus popular plugins, Black, isort, pydocstyle, pyupgrade, and autoflake.
Config lives in pyproject.toml or ruff.toml. The first-party VS Code extension is charliermarsh.ruff. Daily install and command-loop steps live in the Ruff guide.
OpenAI announced it would acquire Astral. Until a close is published, treat Ruff as the same MIT CLI.
ruff formatruff check by handselect is curated and small. "Ruff found nothing" means you have not enabled the codes you care about
Best for existing style stacks you plan to migrate
Flake8 calls itself "Your Tool For Style Guide Enforcement." It wraps PyFlakes, pycodestyle, and McCabe, then loads third-party plugins. That plugin surface is the product.
Maintainer Ian Stapleton Cordasco still ships the wrapper (PyPI 7.3.0). Config lives in .flake8, setup.cfg, or tox.ini. Flake8 does not read pyproject.toml natively.
Teams still run Flake8 when an in-house plugin has nowhere else to go: Ruff will not load it.
E / F / W codes. # noqa: F401 survives a Ruff moveF rules)pyproject.toml, so you keep a second config file after the rest of the stack moved
Best for semantic depth you still cannot get from Ruff
Pylint is a static analyser: errors, coding standard, smells, duplicated code, Pyreverse UML, and Python plugins. Maintainers Pierre Sassoulas and Claudiu Popa still ship 4.x. Config is .pylintrc or pyproject.toml.
Pylint does more type inference than Ruff. Issue #970 still lists cyclic-import and duplicate-code as unchecked (updated 28 July 2026). Pylint's own README now tells you to use Ruff alongside.
On r/learnpython, Pylint threads are mostly VS Code source-roots failures. The other recurring verdict is skip it.
u/eleqtriq (October 2025): "I wouldn't even use pylint. Use ruff or flake8. Ruff is orders of magnitude faster."
source-roots / "No files to lint" before they hit a useful diagnosticAstral documents Ruff as 10-100x faster than existing linters (Flake8) and formatters (Black). Charlie Marsh at PyCon also said "10, 100, even like a thousand times" on large codebases. Treat 1000x as talk-stage and keep 10-100x in the table.
One named 2026 measurement sits beside that range. pyobfuscate ran 1,677 files, F rules, cache off, Ruff 0.16.1 vs Flake8 7.3.0: 0.28 s vs 14.72 s (~53x). That source also sells a WASM linter, so treat it as an independent fixture, not a vendor-neutral lab.
Dagster's Nick Schrock is quoted in the Ruff docs: 250k LOC, Pylint 2.5 min to Ruff 0.4 s.
The FAQ numbers: Pylint ~409 rules, Ruff over 900, of which at least 209 overlap. Both totals move. 900+ is the stable figure.
pyobfuscate's 14-category fixture (Ruff 0.16.3 vs Pylint 4.0.7, cache off) is the only disclosed head-to-head on what each actually flags:
E,F,W,B,BLE,I,PL,RET,SIM,UP,S307): 9/14Pylint-only in that fixture: missing member, missing argument, duplicate code, import cycle, file opened without encoding. Those gaps match #970.
Ruff has what Pylint lacks as a default stack: the Flake8-plugin universe (bugbear B, pyupgrade UP, isort I), autofix, and a formatter. Default Ruff is curated; enable more with --select. select = ["ALL"] on day one is how you get the rules that make code worse.
On r/Python, the argument is which rules to disable.
u/akl773 (August 2026) on FastAPI: B008 bans a function call in a default argument, which is correct in general. Every FastAPI codebase uses Depends() in that position. A blanket ignore then hides the real mutable defaults.
Two paths. Do not flatten them.
Flake8 to Ruff is the default. Ruff can be used as a drop-in replacement for Flake8 when used (1) without or with a small number of plugins, (2) alongside Black, and (3) on Python 3 code. Under those conditions, Ruff implements every rule in Flake8.
Mechanical map: pycodestyle to E,W; pyflakes to F; isort to I; pyupgrade to UP (set target-version or it defaults py310); bugbear to B; Black to ruff format. The old flake8-to-ruff converter is no longer supported (it warns that it may break after Ruff v0.0.233). Map prefixes by hand.
Line-length trap: Flake8's pycodestyle default is 79. Ruff and Black default to 88. Flip line-length before you read the first CI log as a regression.
In-house plugin: keep a minimal Flake8. List leftover plugin codes in lint.external so RUF100 does not strip their # noqa.
Pylint to Ruff is partial. Ruff is not a "pure" drop-in (and vice versa), and enabling Ruff's PL group can add noise from Pylint-extension rules that were not on by default. Move the fast/style layer to Ruff; keep Pylint or a type checker for inference, duplicate code, import cycles, and Python plugins.
Sebastián Ramírez (@tiangolo) collapsed FastAPI's stack onto 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. 🤪
Pytest did the same in February 2024 (Charlie Marsh): autoflake, Black, isort, pyupgrade, Flake8, and pydocstyle in one tool.
Microsoft's linting docs draw the line: linting analyzes how the code runs and detects errors; formatting only restructures how code appears.
Black is still the style default (PSF, PyPI 26.5.x). ruff format is the Black-compatible speed play. Astral's October 2023 claim: over 30x Black and over 99.9% of lines identical on Django and Zulip. The Ruff vs Black page owns that comparison.
Ruff does not type-check. Corey Schafer: Ruff has rules that enforce writing type hints, which is a different job from catching "int passed where str expected." Pair Ruff with mypy, pyright, or basedpyright; those tools are not entries here.
The Ruff extension leads the Pylint extension in Marketplace installs. Both are in the millions. Microsoft's Python linting page still lists first-party Pylint, flake8, mypy and community Ruff.
Skip the old "enable Pylint" checkbox. Microsoft moved linting out of the Python extension. Pylance is a language server and does not lint.
"[python]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
}
}On r/learnpython, the production loop is IDE on save, pre-commit autofix, CI --check only.
u/zanfar (February 2026): "Given that any decent IDE will integrate it, I would assume it's very rare that any developer ever runs it manually."
ruff check + ruff format). Add a type checker beside it.no-member / duplicate-code / import cycles: move style and speed to Ruff; keep Pylint on a slower job, or replace that depth with a type checker.Depends(). Start select = ["E", "F", "I"], not ALL.OpenAI announced the Astral acquisition on 19 March 2026; Astral posted the same day. Terms were not disclosed, and no first-party close date has been published.
Named projects keep collapsing five pre-commit tools into one binary. Charlie Marsh noted Python 3.14 support for uv and Ruff on stable-release day (October 2025). The daily Python experience is uv plus Ruff; the leftover fight is which Ruff rules to turn off.


mypy catches 57% of type errors by default; pyright catches 97%. But mypy 2.1 now outruns pyright on batch CI. Here is the full 2026 breakdown.

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