This content originally appeared on DEV Community and was authored by Ankit Kumar
🧠 1. What is Ruff and Why Use It
Ruff is a fast, all-in-one Python linter, formatter, and import sorter written in Rust.
It replaces multiple tools like Flake8, isort, Black, and pyupgrade, drastically speeding up development and CI pipelines.
⚙️ Key Benefits
Feature | Ruff Advantage |
---|---|
🚀 Speed | 10–100× faster than Flake8 or Pylint |
🧰 All-in-one | Linting + Formatting + Import Sorting |
⚙️ Unified config | Simple setup via pyproject.toml
|
💡 Auto-fix | Many issues can be fixed automatically |
🔧 CI-friendly | Supports GitHub annotations |
🧱 2. Create a Lightweight Example Application
Let’s create a simple Python app: a small To-Do manager.
🗂️ Project structure
todo_app/
├── app/
│ ├── __init__.py
│ ├── main.py
│ └── utils.py
├── tests/
│ └── test_main.py
├── pyproject.toml
├── requirements.txt
└── .github/
└── workflows/
└── lint.yml
🧰 3. Build the Example App
app/main.py
from app.utils import add_task, list_tasks
def main():
print("Welcome to the To-Do App")
add_task("Learn Ruff")
add_task("Integrate Ruff in CI")
print("Your Tasks:")
for task in list_tasks():
print(f"- {task}")
if __name__ == "__main__":
main()
app/utils.py
tasks = []
def add_task(task: str):
"""Add a task to the list."""
if not task:
raise ValueError("Task cannot be empty")
tasks.append(task)
def list_tasks():
"""Return all tasks."""
return tasks
tests/test_main.py
from app.utils import add_task, list_tasks
def test_add_task():
add_task("Task 1")
assert "Task 1" in list_tasks()
📦 4. Install Ruff
pip install ruff
Verify:
ruff --version
⚙️ 5. Configure Ruff with pyproject.toml
Here’s a well-commented configuration file with real-world defaults and examples.
pyproject.toml
[tool.ruff]
# Maximum line length (similar to Black’s default)
line-length = 88
# Specify Python version for compatibility
target-version = "py311"
# Select rulesets to enforce
# Common rule groups:
# E/F = Pycodestyle (errors & warnings)
# W = general warnings
# I = import sorting
# UP = pyupgrade rules (modernize code)
# N = naming conventions
select = ["E", "F", "W", "I", "UP"]
# Ignore specific rule codes if desired
ignore = [
"E501", # ignore line length errors (if you rely on Black)
]
# Exclude certain paths (like virtualenvs or migrations)
exclude = ["venv", "build", "__pycache__", "migrations"]
# Show fixes when applying --fix
show-fixes = true
# Respect .gitignore patterns
respect-gitignore = true
# Auto-detect per-file ignores if necessary
per-file-ignores = { "tests/test_*.py" = ["S101"] }
# Enable incremental mode (optional, speeds up re-runs)
cache-dir = ".ruff_cache"
[tool.ruff.lint.isort]
# Sort imports intelligently
known-first-party = ["app"]
combine-as-imports = true
🧩 6. Useful Ruff Commands
Here’s a table of common Ruff commands with explanations and when to use them:
Command | Description | Use Case |
---|---|---|
ruff check . |
Run all lint checks | ✅ Recommended default |
ruff check . --fix |
Auto-fix lint errors | Use locally/pre-commit |
ruff format . |
Format all Python files | Code beautification |
ruff format --check . |
Check if code is properly formatted | Use in CI |
ruff rule <CODE> |
Get details for a specific rule (e.g., ruff rule E501 ) |
Learn rules |
ruff --explain <CODE> |
Explain why a rule triggered | Debugging |
ruff --help |
Show CLI options | General help |
Recommended CI Command:
ruff check .
It ensures linting consistency, and when combined withruff format --check .
, it gives both lint + format verification without auto-fixing in CI.
🧰 7. (Optional) Pre-commit Hook Setup
Create .pre-commit-config.yaml
:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.15
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
Install:
pip install pre-commit
pre-commit install
Now, Ruff runs automatically before every git commit
.
🧩 8. GitHub Actions CI Integration
Let’s integrate Ruff into a lightweight GitHub Actions pipeline.
.github/workflows/lint.yml
name: Ruff Linting CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install Ruff
run: pip install ruff
# 🔹 Recommended: lint the code (no fixes)
- name: Run Ruff Linter
run: ruff check . --output-format=github
# 🔹 Optional: Check formatting
- name: Check Ruff Formatting
run: ruff format --check .
💡 Why --output-format=github
?
This format makes lint results appear inline as annotations on your PR.
⚡ 9. Run Everything Locally
Try these locally:
ruff check . # Lint check
ruff check . --fix # Auto-fix issues
ruff format . # Format code
pytest # Run tests
📊 10. Benchmark (Optional)
Here’s an example of how fast Ruff runs compared to traditional linters.
Benchmark
🧩 11. Summary — End-to-End Flow
Stage | Command | Purpose |
---|---|---|
Local development | ruff check . --fix |
Lint + auto-fix |
ruff format . |
Format code | |
pytest |
Run tests | |
Pre-commit | pre-commit run --all-files |
Run Ruff before commits |
CI pipeline |
ruff check . & ruff format --check .
|
Verify code cleanliness |
Customization | Edit [tool.ruff] in pyproject.toml
|
Tailor lint rules |
✅ 12. Takeaways
- Ruff = One tool replacing many (Flake8, isort, pyupgrade, partial Black)
- Setup takes <5 minutes and improves local + CI performance drastically
-
Recommended pipeline commands:
ruff check .
ruff format --check .
Configuration is easy via
pyproject.toml
Use
pre-commit
for best developer experience
This content originally appeared on DEV Community and was authored by Ankit Kumar

Ankit Kumar | Sciencx (2025-10-14T09:42:33+00:00) Integrate Ruff into Your Python Application and CI Pipeline: Step-by-Step Guide with Benchmarks. Retrieved from https://www.scien.cx/2025/10/14/integrate-ruff-into-your-python-application-and-ci-pipeline-step-by-step-guide-with-benchmarks/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.