What is Ruff?

Ruff is a lightning-fast Python linter and formatter built in Rust. It combines the functionality of popular tools like isort, flake8, and pyflakes into a single, high-performance package, making it easy to format and lint your entire codebase without managing multiple configurations. By default, Ruff follows many of the style rules defined in PEP 8, Python’s official style guide, helping teams maintain clean, consistent, and readable code across projects.

How to Install it?

Install ruff from PyPi. This will add ruff to your pyproject.toml file as a dev dependency.
uv add --dev ruff

How to lint?

In order to use ruff to lint your repository, run the command below. This will check your entire directory recursively if there are any lint warnings or errors.
uv run ruff check .
If you want to format a specific file or directory, replace . with the directory or filename. The example below will run lint on the tests directory.
uv run ruff check tests

Configuration

By default, ruff has rules to format your code. If you would like to customize this, add specific rules to your pyproject.toml file.
[tool.ruff]
target-version = "py312"
line-length = 88
select = [
    "E",  # pycodestyle errors
    "W",  # pycodestyle warnings
    "F",  # pyflakes
    "I",  # isort
    "B",  # flake8-bugbear
    "C4", # flake8-comprehensions
    "UP", # pyupgrade
]
ignore = [
    "E501",  # line too long, handled by black
    "B008",  # do not perform function calls in argument defaults
    "C901",  # too complex
]
You can also extend your configuration to use other tools. The example below extends ruff to use isort.
[tool.ruff.isort]
force-sort-within-sections = true
known-first-party = ["app"]
force-wrap-aliases = true
combine-as-imports = true
force-single-line = false
lines-after-imports = 2
section-order = [
    "future",
    "standard-library",
    "third-party",
    "first-party",
    "local-folder",
]

Fixing your code

Ruff will fix your code to adhere to the rules. This will attempt at fixing fixable issues based on the rules you have defined.
uv run ruff check --fix .
Sometimes, there will be rules ruff cannot fix by default. You can fix these rules using the --unsafe-fixes argument. This will not fix all your issues but the issues ruff can resolve which may be unsafe to fix automatically.
uv run ruff check --fix --unsafe-fixes .

Formatting

You can add specific formatting configuration which ruff can fix for you.
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
To get ruff to check your formatting, run the following command.
uv run ruff format --check .
To get ruff to format your code, run the following command.
uv run ruff format .

Auto Format

You can setup ruff to format your code automatically. This will look for file changes and format your code when a file is changed.
uv run ruff check --watch .
You can also setup format on save in cursor/vscode. Install the ruff extension https://marketplace.cursorapi.com/items/?itemName=charliermarsh.ruff and then add the following to your .vscode/settings.json file.
{
	"[python]": {
		"editor.defaultFormatter": "charliermarsh.ruff",
           	"editor.formatOnSave": true,
            "editor.codeActionsOnSave": {
                "source.fixAll.ruff": true,
                "source.organizeImports.ruff": true
            }
        }
    }

CICD Pipeline

Having a CICD pipeline to have ruff lint your code automatically saves developers extra time. Here’s how it looks like with github.
name: Lint

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"

      - name: Install uv
        uses: astral-sh/setup-uv@v1
        with:
          version: latest

      - name: Install dependencies
        run: uv sync

      - name: Check formatting
        run: uv run ruff format --check .

      - name: Check linting
        run: uv run ruff check .
Looking for something specific? Visit the official ruff docs: https://docs.astral.sh/ruff/