Ruff
A Python linter and formatter written in Rust that stands in for Flake8 and its plugins, isort, pyupgrade and Black, 10 to 100 times faster.
- What it is
- Linters, formatters and type checkers (linters)
- Type
- Open source
- Made by
- Astral
- License
- MIT
- Facts checked
- 9 October 2026
What it is
Ruff parses each Python file once and runs its rules over the syntax tree: 968 of them by the count in the 0.16 release notes, re-implementing Pyflakes, pycodestyle, isort, pyupgrade, flake8-bugbear and dozens of other Flake8 plugins natively. Rules are picked by code or prefix (F401, UP, B), and most findings carry a fix that ruff check --fix applies; fixes that could change behaviour are marked unsafe and need an explicit opt-in. Since 0.16 (July 2026) 413 rules are on by default, up from 59, so an unconfigured project already gets import sorting and pyupgrade checks. The same binary also formats: ruff format is designed as a drop-in for Black and formats more than 99.9% of lines identically on Black-formatted projects such as Django, and since 0.16 it also formats Python code blocks inside Markdown files. Configuration lives in pyproject.toml or ruff.toml, with the closest file winning, as in ESLint. ruff server is a language server built into the CLI and powers the VS Code extension.
Ruff is a linter, not a type checker; its own FAQ recommends pairing it with a type checker such as Astral’s ty, mypy, Pyright or Pyre. It is built by Astral, which announced in March 2026 an agreement to join OpenAI’s Codex team and says it will keep developing its tools in the open. Ruff is still 0.x: the minor version marks breaking changes, and 0.17.0 (October 2026) raised the default target to Python 3.11 and trimmed the default rule set again.
Why teams pick it
- Speed: about 150 times faster than Flake8 at its first release, and its formatter over 30 times faster than Black at launch
- One tool and one config section replace Flake8 with its plugins, isort, pyupgrade, autoflake and Black
- Automatic fixes for most findings, with risky ones clearly marked unsafe
- Useful with zero configuration since 0.16, and new rules wait in preview for at least one minor release before becoming stable
Watch out for
- No custom or third-party rules: a Flake8 plugin is only available if Ruff’s maintainers re-implement it in Rust
- No type checking; you still need mypy, Pyright, basedpyright, Pyrefly or ty beside it
- Pre-1.0 versioning: minor releases change defaults (0.16 grew the default rule set from 59 to 413 rules), so pin the version
- The formatter differs from Black in a few deliberate ways; Ruff advises against alternating the two on the same code
Alternatives
What all linters have in common →How it fits with other technologies
Lint and format a file with no configuration (Ruff 0.17.0, default rule set) · bash
uvx ruff check --output-format concise
# orders.py:1:1: I001 [*] Import block is un-sorted or un-formatted
# orders.py:1:8: F401 [*] `os` imported but unused
# orders.py:9:11: UP045 [*] Use `X | None` for type annotations
# Found 3 errors.
# [*] 3 fixable with `--fix`.
uvx ruff rule F401 | head -3 # every rule documents itself
# # unused-import (F401)
# Derived from the **Pyflakes** linter.
uvx ruff format --check # what CI runs: report, exit 1, change nothing
# - orders=[Order(id=1, total_cents=1299), Order(id=2, total_cents=450)]
# + orders = [Order(id=1, total_cents=1299), Order(id=2, total_cents=450)]
# 1 file would be reformatted
uvx ruff check --fix && uvx ruff format
# Found 3 errors (3 fixed, 0 remaining).
# 1 file reformattedSee it in a real stack
No architecture uses Ruff yet. Drop it into the playground and wire it up yourself.Open playground →Where it came from2022–2026
In August 2022 Charlie Marsh pointed at the JavaScript world, where esbuild, swc and Bun had shown that tools rewritten in faster languages could be 10 to 100 times quicker, and argued Python tooling could be “much, much faster”. As a proof of concept Marsh released Ruff, a linter written in Rust on top of RustPython’s parser: about 150 times faster than Flake8 when linting CPython on macOS, with ESLint-style caching and pyproject.toml configuration. Marsh called it “rough” and not a drop-in replacement yet.
Adoption was quick. By April 2023 Ruff had passed a million monthly downloads and was used by Airflow, FastAPI, pandas and SciPy, and Marsh founded Astral with $4 million of seed funding led by Accel to keep building it. The Ruff formatter followed in October 2023, aiming at Black compatibility rather than a new style, and a built-in language server replaced the separate ruff-lsp in 2024.
Astral went on to build uv and ty around the same principles. In March 2026 it agreed to join OpenAI’s Codex team, and Ruff kept shipping: 0.16 in July 2026 expanded the default rule set from 59 to 413 rules.
Why it’s built this way
- Rewrite the linter in Rust
- Marsh’s hypothesis was that Python tooling could be rewritten in faster languages; the speed-up turned a 12-second lint of CPython into roughly real-time feedback.
- Re-implement popular plugins instead of loading them
- Keeping every rule native in Rust preserves the speed and one consistent interface, at the cost of user-written rules.
- Copy Black’s style rather than invent one
- Black was already the de facto style, so near-identical output let projects switch formatters with almost no diff.
- Rules start in preview
- New rules stay in preview for at least one minor release before they become stable, so upgrades don’t surprise teams with untested checks.
Timeline
- 2022
Ruff released in August as a proof of concept
- 2023
Astral founded in April; the Ruff formatter arrives in October
- 2024
ruff server, a built-in language server, replaces ruff-lsp - 2026
March: Astral agrees to join OpenAI’s Codex team
- 2026
July: 0.16 enables 413 rules by default and formats Markdown code blocks
- 2026
October: 0.17 targets Python 3.11 by default
- Charlie Marsh: Python tooling could be much, much faster (Aug 2022)
- Astral blog: Announcing Astral, the company behind Ruff (Apr 2023)
- Astral blog: The Ruff formatter (Oct 2023)
- Ruff docs: Editor integrations (ruff server, v0.4.5 beta, v0.5.3 stable)
- Astral blog: Ruff v0.4.5, Ruff’s language server is now in beta (May 2024)
- Astral blog: Astral to join OpenAI (Mar 2026)
- Astral blog: Ruff v0.16.0 (Jul 2026)
- Ruff v0.17.0 release notes (Oct 2026)
- Ruff docs: Versioning (preview rules)
Sources14 · facts checked 9 October 2026
- Ruff README (speed, tools it replaces, licence)
- Ruff docs: The Ruff linter (fixes, rule selection)
- Ruff docs: Rules
- Ruff docs: The Ruff formatter (Black compatibility, Markdown)
- Ruff docs: Configuring Ruff (hierarchical configuration)
- Ruff FAQ (type checkers, custom rules, Flake8 plugins)
- Ruff docs: Editor integrations
- Ruff docs: Editor setup (VS Code extension)
- Ruff docs: Integrations (GitHub Actions)
- Ruff docs: Versioning
- Astral blog: Ruff v0.16.0 (Jul 2026)
- Ruff v0.17.0 release notes (Oct 2026)
- Astral blog: The Ruff formatter (Oct 2023)
- Astral blog: Astral to join OpenAI (Mar 2026)