How do Ruff and Pylint compare?
Ruff covers most of Pylint’s common checks and runs orders of magnitude faster. Pylint adds duplicate-code detection and deeper semantic analysis that Ruff doesn’t yet implement. For most new projects, Ruff is the right default.
How does speed compare?
Ruff’s Rust implementation processes Python files orders of magnitude faster than Pylint’s Python codebase. The gap is most noticeable in large codebases and CI pipelines, where Pylint’s full-program analysis can take tens of seconds on a project with thousands of files.
How do the rule sets compare?
Pylint implements approximately 409 rules; Ruff covers over 950, with around 209 overlapping. Ruff’s broader coverage comes from reimplementing popular linting plugins (flake8-bugbear, flake8-comprehensions, and others) natively.
What Pylint uniquely offers is semantic analysis beyond pattern matching: it validates call signatures against function definitions, detects duplicate code across files (R0801), and checks method and class naming at a level Ruff doesn’t yet reach. These checks require Pylint to build a full program model, which is also what makes it slower.
Ruff does implement McCabe cyclomatic complexity checking via the C901 rule (the C90 rule group). Enable it with select = ["C90"] in [tool.ruff.lint]; it is off by default.
Note
Astral (now part of OpenAI) also maintains ty, a type checker that covers the deeper analysis Ruff doesn’t handle: argument validation and type inference.
Does Ruff fix code automatically?
Yes. Run ruff check --fix and Ruff rewrites the violations it can correct: unused imports disappear, import order changes, and deprecated syntax gets updated. Pylint reports issues without rewriting code.
Does Pylint support plugins?
Pylint’s plugin system lets teams write custom checkers in Python and load them with --load-plugins. This is useful for domain-specific rules (enforcing internal naming standards, banning certain API calls) that no general-purpose linter ships by default. Ruff implements all rules natively and does not support custom plugins.
How do you run both tools together?
The most common combination runs Ruff for speed and breadth, then layers Pylint for the checks it uniquely handles:
- Ruff: fast style enforcement and common-pattern detection, run on save or in pre-commit hooks
- Pylint: duplicate-code detection and deeper semantic analysis, run in CI
- ty or mypy: argument and type validation
ruff check --fix . # auto-fix common issues
ruff format . # format code
pylint src/ # deeper semantic analysis in CIBoth tools read configuration from pyproject.toml. How to replace Black, isort, flake8, and pyupgrade with Ruff covers adding Ruff to an existing project step by step.