Home Python Ruff: Supercharge Your Python Linting and Formatting
Beginner 3 min · July 14, 2026
Ruff: Fast Python Linter and Formatter

Ruff: Supercharge Your Python Linting and Formatting

Learn Ruff, the ultra-fast Python linter and formatter.

N
Naren Founder & Principal Engineer

20+ years shipping production Python across data and backend systems. Written from production experience, not tutorials.

Follow
Production
production tested
July 15, 2026
last updated
2,398
articles · all by Naren
Before you start⏱ 15-20 min read
  • Basic knowledge of Python syntax and common linters (Flake8, Black).
  • Python 3.7+ installed on your system.
  • Familiarity with command-line tools and configuration files.
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Ruff is a Rust-based linter and formatter that is 10-100x faster than Flake8 and Black.
  • It replaces multiple tools (Flake8, isort, Black, pyflakes) with a single binary.
  • Configuration is done via pyproject.toml or ruff.toml.
  • It supports over 700 lint rules and automatic fix.
  • Ideal for CI/CD pipelines and pre-commit hooks.
✦ Definition~90s read
What is Ruff?

Ruff is an extremely fast Python linter and formatter written in Rust, designed to replace multiple traditional tools.

Think of Ruff as a super-fast code inspector and auto-cleaner.
Plain-English First

Think of Ruff as a super-fast code inspector and auto-cleaner. While other tools take minutes to check your code, Ruff does it in seconds, like a race car compared to a bicycle. It catches mistakes, enforces style, and even fixes many issues automatically.

As your Python projects grow, maintaining code quality becomes critical. Linters and formatters help enforce consistent style and catch bugs early. But traditional tools like Flake8, Black, and isort can be slow, especially on large codebases. Enter Ruff: a blazing-fast linter and formatter written in Rust. Ruff is designed to be a drop-in replacement for many existing tools, offering 10-100x speed improvements.

Ruff supports over 700 lint rules, including those from Flake8, pyflakes, pycodestyle, and isort. It also provides automatic fixes for many issues. Its speed makes it ideal for pre-commit hooks and CI pipelines, where every second counts. In this tutorial, you'll learn how to install Ruff, configure it for your project, integrate it into your workflow, and debug common issues in production. By the end, you'll be able to supercharge your Python development with minimal effort.

Installing Ruff

Ruff is distributed as a single binary, making installation simple. You can install it via pip, Homebrew, or download the binary from GitHub. The recommended way is using pip:

``bash pip install ruff ``

``bash brew install ruff ``

``bash ruff --version ``

Ruff also supports installation as a pre-commit hook. Add this to your .pre-commit-config.yaml:

``yaml - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.1.0 hooks: - id: ruff args: [--fix] - id: ruff-format ``

This ensures Ruff runs automatically before each commit, catching issues early.

install_ruff.pyPYTHON
1
2
3
# No code needed, installation is via command line
# pip install ruff
# ruff --version
Output
ruff 0.1.0
💡Install via pipx for isolated environment
📊 Production Insight
In CI, cache the Ruff binary to avoid re-downloading on every run.
🎯 Key Takeaway
Ruff installs as a single binary and can be used as a pre-commit hook.

Configuring Ruff

Ruff is configured via pyproject.toml or a dedicated ruff.toml file. The configuration allows you to select rules, ignore certain files, and set formatting options. Here's a basic example:

```toml [tool.ruff] # Enable pycodestyle (E), pyflakes (F), and isort (I) rules. select = ["E", "F", "I"]

# Ignore line length violations in tests. ignore = ["E501"]

# Exclude generated files. exclude = [".pyc", "__pycache__", "migrations/"]

# Line length. line-length = 88

[tool.ruff.format] # Use single quotes instead of double quotes. quote-style = "single" ```

``toml [tool.ruff.per-file-ignores] "__init__.py" = ["F401"] ``

Ruff supports many rule categories: E (pycodestyle), F (pyflakes), I (isort), N (naming), and more. Use ruff linter to list all rules.

``bash ruff check --show-settings ``

pyproject.tomlPYTHON
1
2
3
4
5
6
7
8
9
10
11
[tool.ruff]
select = ["E", "F", "I", "N"]
ignore = ["E501"]
exclude = ["*.pyc", "__pycache__", "migrations/*"]
line-length = 88

[tool.ruff.format]
quote-style = "single"

[tool.ruff.per-file-ignores]
"__init__.py" = ["F401"]
🔥Rule Selection
📊 Production Insight
Use per-file ignores for generated files or legacy code that cannot be changed immediately.
🎯 Key Takeaway
Ruff configuration is done via pyproject.toml, allowing fine-grained control over rules and formatting.

Running Ruff as a Linter

Ruff's linter checks your code for errors, style violations, and anti-patterns. To run the linter, use:

``bash ruff check . ``

This will scan all Python files in the current directory. You can also specify individual files:

``bash ruff check myfile.py ``

``bash ruff check --fix . ``

For unsafe fixes (e.g., removing unused imports that might have side effects), use --unsafe-fixes:

``bash ruff check --fix --unsafe-fixes . ``

``bash ruff check --fix --show-fixes . ``

You can also output results in different formats, like JSON for CI integration:

``bash ruff check --output-format json . ``

example_lint.pyPYTHON
1
2
3
4
5
6
7
8
9
10
# Before linting
import os
import sys

def foo():
    x = 1
    y = 2
    print(x + y)

foo()
Output
example_lint.py:1:1: F401 `os` imported but unused
example_lint.py:2:1: F401 `sys` imported but unused
example_lint.py:4:1: E302 expected 2 blank lines, found 1
⚠ Unsafe Fixes
📊 Production Insight
In CI, run ruff check --output-format github to annotate pull requests with lint errors.
🎯 Key Takeaway
Use ruff check to lint and --fix to auto-correct issues. Unsafe fixes require manual review.

Formatting Code with Ruff

Ruff also includes a formatter, which is an alternative to Black. It aims to be compatible with Black's style but faster. To format your code, run:

``bash ruff format . ``

``bash ruff format --diff . ``

Ruff's formatter respects the line-length setting from your configuration. It also supports options like quote-style (single or double quotes) and indent-style (spaces or tabs).

```python # Before formatting def my_function( arg1,arg2 ): return arg1+arg2

# After ruff format def my_function(arg1, arg2): return arg1 + arg2 ```

Ruff's formatter is designed to be deterministic and consistent, reducing debates about code style.

format_example.pyPYTHON
1
2
3
4
5
6
7
# Before
x = [1,2,3,4,5]
y = { 'a':1,'b':2 }

# After ruff format
x = [1, 2, 3, 4, 5]
y = {"a": 1, "b": 2}
💡Integrate with Editor
📊 Production Insight
Use ruff format --check in CI to ensure code is formatted without modifying files.
🎯 Key Takeaway
Ruff format is a fast, deterministic formatter that replaces Black.

Integrating Ruff with Pre-commit

Pre-commit hooks automate code quality checks before each commit. Ruff provides official pre-commit hooks for both linting and formatting. Add the following to your .pre-commit-config.yaml:

``yaml repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.1.0 hooks: - id: ruff args: [--fix] - id: ruff-format ``

Then run pre-commit install to activate the hooks. Now, every time you commit, Ruff will lint and format your staged files. If issues are found, the commit will be blocked until fixed.

``bash pre-commit run --all-files ``

This integration ensures consistent code quality across the team.

.pre-commit-config.yamlPYTHON
1
2
3
4
5
6
7
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.1.0
    hooks:
      - id: ruff
        args: [--fix]
      - id: ruff-format
🔥Pre-commit vs CI
📊 Production Insight
Use args: [--exit-non-zero-on-fix] to fail the commit if Ruff makes changes, requiring a re-commit.
🎯 Key Takeaway
Pre-commit hooks with Ruff enforce linting and formatting before commits.

Advanced Configuration: Rule Selection and Ignoring

Ruff offers granular control over which rules to apply. You can select entire categories or individual rules. For example:

``toml [tool.ruff] select = ["E", "F", "I", "N", "W"] ignore = ["E501", "W191"] ``

You can also enable rules that are not part of any category using their full code (e.g., RUF100).

``toml [tool.ruff.per-file-ignores] "tests/*" = ["S101"] # Allow assert in tests "__init__.py" = ["F401"] # Allow unused imports ``

Ruff also supports extend-select and extend-ignore to add rules from different sources.

``toml [tool.ruff.format] quote-style = "double" indent-style = "space" line-ending = "lf" ``

These settings help tailor Ruff to your project's needs.

advanced_config.tomlPYTHON
1
2
3
4
5
6
7
8
9
10
11
[tool.ruff]
select = ["E", "F", "I", "N", "W", "RUF100"]
ignore = ["E501"]

[tool.ruff.per-file-ignores]
"tests/*" = ["S101"]
"__init__.py" = ["F401"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
⚠ Avoid Over-Configuring
📊 Production Insight
Use ruff check --statistics to see which rules are triggered most often and adjust configuration accordingly.
🎯 Key Takeaway
Ruff allows per-file ignores and fine-grained rule selection for flexibility.

Performance Benchmarks and CI Integration

Ruff's main selling point is speed. In benchmarks, Ruff is 10-100x faster than Flake8 and Black. For example, on a 10,000-file codebase, Flake8 might take 5 minutes, while Ruff finishes in under 10 seconds. This speed makes it ideal for CI pipelines where every second counts.

``yaml - name: Lint with Ruff run: | pip install ruff ruff check --output-format github . ``

``yaml - name: Check formatting with Ruff run: | pip install ruff ruff format --check . ``

``yaml - name: Cache Ruff uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-ruff-${{ hashFiles('pyproject.toml') }} ``

This ensures fast, consistent checks.

ci.ymlPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
name: Lint
on: [push, pull_request]
jobs:
  ruff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install Ruff
        run: pip install ruff
      - name: Run Ruff linter
        run: ruff check --output-format github .
      - name: Check formatting
        run: ruff format --check .
🔥GitHub Annotations
📊 Production Insight
Always use the latest Ruff version in CI to benefit from performance improvements and new rules.
🎯 Key Takeaway
Ruff's speed makes it perfect for CI, reducing feedback loops.
● Production incidentPOST-MORTEMseverity: high

The Slow CI Pipeline That Cost Hours

Symptom
Developers waited 15+ minutes for linting checks to pass before merging.
Assumption
The team assumed slow linting was normal for a large monorepo.
Root cause
Flake8 and Black were running sequentially on thousands of files, consuming excessive CPU.
Fix
Replaced Flake8 and Black with Ruff, reducing linting time to under 30 seconds.
Key lesson
  • Always profile your CI pipeline to identify bottlenecks.
  • Consider replacing multiple tools with a single, faster alternative.
  • Ruff's speed makes it ideal for large codebases.
  • Use pre-commit hooks with Ruff to catch issues before CI.
  • Monitor tool versions and updates for performance improvements.
Production debug guideSymptom to Action5 entries
Symptom · 01
Ruff is not running on certain files
Fix
Check if the file is excluded in pyproject.toml or if the file extension is not .py.
Symptom · 02
Ruff reports false positives
Fix
Disable the specific rule using --ignore or per-file ignores.
Symptom · 03
Ruff formatting changes are unexpected
Fix
Review the Ruff style guide and use --diff to preview changes.
Symptom · 04
Ruff is slow in CI
Fix
Ensure you are using the latest version and cache the Ruff binary.
Symptom · 05
Ruff conflicts with other formatters
Fix
Remove other formatters and rely solely on Ruff for consistency.
★ Quick Debug Cheat SheetCommon Ruff issues and immediate actions.
Rule not found
Immediate action
Check rule code spelling
Commands
ruff check --select RUF100
ruff rule RUF100
Fix now
Use correct rule code
Formatting disagreement+
Immediate action
Preview changes
Commands
ruff format --diff
ruff format
Fix now
Run ruff format to apply
File ignored unexpectedly+
Immediate action
Check exclude patterns
Commands
ruff check --show-files
cat pyproject.toml | grep exclude
Fix now
Adjust exclude in config
Lint error not auto-fixable+
Immediate action
Check if rule supports fix
Commands
ruff rule <RULE_CODE>
ruff check --fix --unsafe-fixes
Fix now
Manually fix or use unsafe fixes
FeatureRuffFlake8Black
Speed10-100x fasterSlowModerate
Rules700+~300N/A
Auto-fixYesLimitedN/A
FormatterBuilt-inNoYes
Configurationpyproject.tomlSeparate filespyproject.toml
LanguageRustPythonPython
⚙ Quick Reference
6 commands from this guide
FileCommand / CodePurpose
pyproject.toml[tool.ruff]Configuring Ruff
example_lint.pydef foo():Running Ruff as a Linter
format_example.pyx = [1,2,3,4,5]Formatting Code with Ruff
.pre-commit-config.yamlrepos:Integrating Ruff with Pre-commit
advanced_config.toml[tool.ruff]Advanced Configuration
ci.ymlname: LintPerformance Benchmarks and CI Integration

Key takeaways

1
Ruff is a fast, all-in-one linter and formatter that replaces Flake8, isort, and Black.
2
Configuration is done via pyproject.toml with fine-grained rule selection and per-file ignores.
3
Integrate Ruff with pre-commit hooks and CI for automated code quality checks.
4
Use ruff check --fix for auto-fixes and ruff format for formatting.
5
Ruff's speed makes it ideal for large codebases and CI pipelines.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is Ruff and how does it differ from traditional linters like Flake8...
Q02SENIOR
How would you configure Ruff to ignore line length violations in test fi...
Q03SENIOR
Explain how Ruff achieves its speed advantage over other linters.
Q01 of 03JUNIOR

What is Ruff and how does it differ from traditional linters like Flake8?

ANSWER
Ruff is a Rust-based linter and formatter that is significantly faster than Flake8 and Black. It combines multiple tools into one binary and supports over 700 rules.
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
Is Ruff a drop-in replacement for Flake8 and Black?
02
Can I use Ruff alongside other linters?
03
How do I ignore a specific rule for a single line?
04
Does Ruff support Python 2?
05
How do I update Ruff?
N
Naren Founder & Principal Engineer

20+ years shipping production Python across data and backend systems. Written from production experience, not tutorials.

Follow
Verified
production tested
July 15, 2026
last updated
2,398
articles · all by Naren
🔥

That's Advanced Python. Mark it forged?

3 min read · try the examples if you haven't

Previous
Numba JIT: High-Performance Python Compilation
24 / 35 · Advanced Python
Next
Pre-commit Hooks for Python Projects