Ruff, el linter y formatter moderno de Python

Intermedio
Python
Python
Actualizado: 19/04/2026

Qué es Ruff y qué reemplaza

Ruff es una herramienta de análisis estático para Python creada por Astral. Ofrece dos comandos principales:

  • ruff check: detecta errores de estilo, bugs potenciales y malas prácticas.
  • ruff format: formatea el código siguiendo reglas consistentes de estilo.

Está implementada en Rust y es típicamente 10 a 100 veces más rápida que las herramientas Python tradicionales. Donde flake8 tarda 10 segundos en un repositorio grande, ruff tarda menos de 100 milisegundos.

Lo más importante es que sustituye a varias herramientas a la vez. Una única instalación de ruff cubre el trabajo de:

  • flake8 (linter general)
  • pylint (linter avanzado)
  • isort (ordenar imports)
  • black (formateador)
  • pydocstyle (estilo de docstrings)
  • pyupgrade (sintaxis moderna)
  • autoflake (eliminar imports y variables no usadas)
  • bugbear (detección de bugs habituales)

Ruff implementa más de 800 reglas cubriertas por las herramientas anteriores, con una compatibilidad muy alta. Si venías de un proyecto con flake8 + black + isort, migrar a ruff suele ser inmediato.

Instalación

Ruff se instala como dependencia de desarrollo del proyecto. Lo habitual con uv es:

uv add --dev ruff

Con pip:

pip install ruff

También puede instalarse globalmente como herramienta con uv tool o pipx:

uv tool install ruff

Verifica la instalación:

ruff --version

ruff check: el linter

ruff check analiza el código en busca de problemas. Ejecútalo sobre un directorio o archivo:

ruff check .
ruff check src/
ruff check src/app.py

Por defecto, ruff check muestra cada problema con su ubicación, el código de regla y un mensaje:

src/app.py:12:1: F401 'os' imported but unused
src/app.py:25:5: E501 line too long (105 > 88 characters)
src/utils.py:8:9: B006 do not use mutable default arguments

Muchas reglas tienen autofix (corrección automática). Añade --fix para aplicarlas:

ruff check --fix .

Para ver exactamente qué reglas están activas sin aplicar nada:

ruff check --no-fix .

Para ver cambios sin aplicar (dry-run):

ruff check --fix --diff .

ruff format: el formateador

ruff format aplica un formato consistente al código fuente, al estilo de black. La compatibilidad con black es prácticamente del 100 por cien, por lo que migrar es trivial.

ruff format .             # formatear in-place
ruff format --check .      # no formatear, solo comprobar
ruff format --diff src/   # ver qué cambiaría

En CI se usa habitualmente ruff format --check junto con ruff check para fallar el pipeline si el código no cumple las reglas.

Configuración en pyproject.toml

La configuración de Ruff vive dentro de pyproject.toml bajo la sección [tool.ruff]. Un arranque razonable para un proyecto profesional:

[tool.ruff]
line-length = 100
target-version = "py313"

[tool.ruff.lint]
select = [
    "E",    # pycodestyle errors
    "W",    # pycodestyle warnings
    "F",    # pyflakes
    "I",    # isort
    "B",    # flake8-bugbear
    "N",    # pep8-naming
    "UP",   # pyupgrade
    "SIM",  # flake8-simplify
    "PT",   # flake8-pytest-style
    "RUF",  # reglas específicas de ruff
]
ignore = [
    "E501",  # gestionado por el formateador
]

[tool.ruff.lint.per-file-ignores]
"tests/*" = ["S101"]  # permitir asserts en tests

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

Las reglas se identifican por prefijos que agrupan categorías completas. Por ejemplo, "UP" activa todas las reglas de pyupgrade que detectan sintaxis antigua (uso de typing.List en lugar de list[...], Optional[X] en lugar de X | None, etcetera).

La sección select es explícita: solo se activan las reglas listadas. Es más predecible que "activar todo y desactivar lo que moleste", y facilita que el equipo vea qué reglas se aplican con un simple vistazo al pyproject.toml.

Reglas útiles por defecto

Algunas reglas de alto valor que conviene activar desde el primer día:

F401 (unused imports): detecta imports que sobran y puede eliminarlos automáticamente.

F841 (unused variable): detecta variables locales asignadas pero nunca usadas.

B006 (mutable default argument): atrapa el bug clásico de def f(items=[]) que causa estado compartido entre llamadas.

UP006 y UP007: migran a sintaxis moderna. List[int] se convierte en list[int]; Optional[int] se convierte en int | None.

I001: ordena imports igual que isort, agrupando stdlib, terceros y locales.

SIM108: simplifica if-else a expresiones ternarias cuando procede.

PT003: en pytest, usa @pytest.fixture() en lugar de @pytest.fixture para ser consistente.

Integración con el editor

La mayoría de editores modernos tienen integración nativa con Ruff vía el Language Server Protocol. En IntelliJ IDEA y PyCharm, basta con instalar el plugin oficial de Ruff. En Neovim o similares, existen plugins dedicados que lanzan ruff server automáticamente.

Tras configurar el LSP, el editor muestra errores en tiempo real, aplica autofix al guardar y formatea con un atajo de teclado. Es la forma recomendada de trabajar.

Integración con pre-commit y CI

Para asegurar que el código que entra al repositorio cumple las reglas, Ruff se integra con pre-commit:

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

En CI, el flujo tipico es un paso que ejecuta:

uv run ruff check .
uv run ruff format --check .

Si alguno falla, el pipeline no continúa. Esto garantiza un estilo consistente en toda la base de código sin depender de la disciplina individual.

Migración desde flake8, black e isort

Si tu proyecto ya usa flake8 + black + isort, la migración suele consistir en:

1 Instalar ruff como dependencia de desarrollo.

2 Trasladar configuración equivalente de .flake8, pyproject.toml y setup.cfg a la sección [tool.ruff.lint].

3 Ejecutar ruff check --fix . y ruff format . una vez sobre todo el código para alinear el estilo.

4 Eliminar las dependencias antiguas (flake8, black, isort) de pyproject.toml.

5 Actualizar CI y pre-commit para usar solo ruff.

La ganancia inmediata es tiempo: pipelines de CI que tardaban minutos pasan a segundos. Y a medio plazo, tener una sola herramienta con una sola configuración simplifica la mantención del proyecto.

Ruff es, junto a uv y pydantic, una de las herramientas de Astral y la comunidad que han redefinido el desarrollo Python profesional en los últimos dos años.

Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Python es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Python

Explora más contenido relacionado con Python y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Instalar ruff en un proyecto Python. Usar ruff check para detectar errores de estilo y problemas comunes. Usar ruff format como reemplazo de black. Configurar reglas activas en pyproject.toml. Integrar ruff con el editor y con la CI.