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.

License Python versions PyPI version


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=N for 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: Rule and LineRule base classes

  • Plugin system — Entry points + local rules + pyproject.toml config

  • Error 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.