Write custom lint rules in Python. Run them at Rust speed.
The custom rules linter that Ruff can't be and Flake8 refuses to become.
Your rules. Python API. Rust engine.
17x faster than Flake8. 2x faster on 1 core than Flake8 on 16.
Ruff for standards. Rude for your standards.
Custom lint rules shouldn't cost you 1 GB of RAM.
Flake8 refused pyproject.toml. We refused Flake8.
Flake8 speed at 16 cores. Rude speed at 1.
Scopes, bindings, qualified names — in your Python rules, at zero cost.
Rude¶
Rude is a fast, extensible Python linter built for teams that need their own rules — not just PEP 8. It pairs a tree-sitter parser with a Rust-powered semantic engine to give your Python rules access to scopes, bindings, and qualified names — without the overhead.
Getting started¶
pip install rude
rude check src/
See the installation guide and quickstart for more options.
Write your first rule¶
from collections.abc import Iterator
from rude import Diagnostic, Node, NodeType, Rule
class NoAssertInProd(Rule):
"""ACME001 - `assert` should not appear in production code.
Skips the check in test files (whose path contains a `tests/` or
`test/` segment, or whose name starts with `test_` / ends with
`_test.py`) so the rule does not flag test-suite assertions.
"""
code = "ACME001"
message = "`assert` should not appear outside test files"
node_types = {NodeType.ASSERT_STATEMENT}
def check(self, node: Node) -> Iterator[Diagnostic]:
if node.ctx.is_test_file():
return
yield self.diagnostic(node)
See the custom rules guide for autofixes, plugins, and advanced patterns.
Key features¶
Fast — tree-sitter parsing + Rust semantic engine (~17x faster than Flake8;
--jobs=Nfor multiprocess Python rule parallelism)Autofix — Rules can provide automatic fixes with import management
Advanced analysis — Scope tracking, qualified name resolution via Rust/PyO3
Extensible — Simple Python API:
RuleandLineRulebase classesPlugin system — Entry points + local rules +
pyproject.tomlconfigError recovery — Lints partially even with syntax errors
The sweet spot¶
Standard rules |
Custom rules |
Speed |
Memory |
|
|---|---|---|---|---|
Ruff |
800+ |
none |
fastest |
low |
Rude |
147 (104 + plugins) |
unlimited |
fast |
low |
Flake8 |
100+ (plugins) |
via packages |
slow |
medium |
Fixit |
~30 |
via LibCST |
slow |
high |
Why not just use…¶
Ruff? Ruff is incredible for standard rules — but it doesn’t support custom rules in Python. Rude is designed as a companion to Ruff, not a replacement.
Flake8? Flake8 is 17x slower, still can’t read pyproject.toml without a
third-party plugin, and requires
publishing a package just to add a custom rule.
Fixit? Fixit uses 17x more memory than Rude on the same codebase (1,059 MB vs 61 MB on Django), has no parallel execution, and users report hour-long CI runs.
Getting Started
Writing Rules
Built-in Rules