TL;DR: Ruff는 Rust로 작성된 Python 코드 검사 도구(linter + formatter)로, Flake8보다 10~100배 빠릅니다. 30만 줄 코드가 들어간 초대형 프로젝트를 0.5초 만에 검사할 수 있습니다. 2026년 현재 Ruff는 Python 생태계의 사실상 표준 코드 품질 도구로 자리 잡았으며, Instagram, PyTorch, Jupyter, Apache Airflow 등 유명 프로젝트에서 채택하고 있습니다. 이 글에서는 Ruff를 처음부터 사용하는 법, 설치, 설정, Flake8/Black/isort에서 완전히 마이그레이션하는 가이드를 다룹니다.

1. Ruff란 무엇인가?

Ruff는 Astral 팀이 개발했으며(uv와 동일한 팀), Rust로 작성된 Python 생태계의 올인원 코드 검사 도구입니다. 여러 독립 도구의 기능을 하나로 통합했습니다:

대체 대상 도구 기능 Ruff 규칙 접두사
Flake8 코드 스타일 검사 F, E, W
Black 코드 포매팅 -
isort import 정렬 I
pyupgrade Python 버전 업그레이드 권장 UP
pylint 고급 코드 검사 PL, SIM, C901
autoflake 미사용 import 자동 제거 F401, F841

Ruff는 왜 이렇게 빠를까?

  1. Rust 컴파일: Rust의 성능은 Python을 압도합니다. 파싱 속도에서桁수 차이가 납니다.
  2. 병렬 처리: 멀티코어 CPU를 자동으로 활용해 파일을 병렬로 스캔합니다.
  3. 제로 의존성: Python 런타임이 필요 없습니다. 단일 바이너리 파일로 실행됩니다.
  4. 증분 캐시: 변경된 파일만 검사하므로 두 번째 실행은 거의 순간적으로 완료됩니다.

Ruff GitHub 저장소: https://github.com/astral-sh/ruff ⭐ 2026년 기준 35,000개 이상의 Star를 돌파했습니다.

2. Ruff 설치

Ruff는 다양한 방법으로 설치할 수 있으며, pip 또는 공식 설치 스크립트를 권장합니다:

BASH
# 방법 1: pip 사용 (권장)
pip install ruff

# 방법 2: uv 사용 (더 빠름)
uv tool install ruff

# 방법 3: macOS Homebrew
brew install ruff

# 방법 4: 공식 설치 스크립트
curl -LsSf https://astral.sh/ruff/install.sh | sh

# 설치 확인
ruff --version
# 출력: ruff 0.9.x

설치가 완료되면 Ruff는 두 가지 주요 명령을 제공합니다:

  • ruff check: 코드 검사 (linter 모드)
  • ruff format: 코드 포매팅 (formatter 모드)

3. 빠른 시작: 5분 만에 프로젝트 검사하기

테스트 파일 hello.py를 만들어 보세요:

PYTHON
import os
import sys
import json  # unused

def  hello_world():
    x=1+2
    print("hello world")
    return x

if __name__ == "__main__":
    hello_world()

3.1 코드 검사 실행

BASH
ruff check hello.py

출력 예시:

hello.py:1:8: F401 [*] `os` imported but unused
hello.py:2:8: F401 [*] `sys` imported but unused
hello.py:3:8: F401 [*] `json` imported but unused
hello.py:5:1: W293 [*] Blank line contains whitespace
hello.py:7:6: E225 [*] Missing whitespace around operator
Found 5 errors.
[*] 5 fixable with the `--fix` option.

Ruff가 5가지 문제를 정확히 찾아냈습니다: 미사용 import 3개, 불필요한 빈 줄 1개, 연산자 주위 공백 누락 1개. 각 오류마다 --fix로 자동 수정 가능한지 표시되어 있습니다.

3.2 자동 수정

BASH
ruff check --fix hello.py

실행 후 파일이 자동으로 수정됩니다:

PYTHON
def hello_world():
    x = 1 + 2
    print("hello world")
    return x

if __name__ == "__main__":
    hello_world()

3.3 코드 포매팅

BASH
ruff format hello.py

ruff format은 Black과 유사하게 들여쓰기, 빈 줄, 따옴표 스타일 등을 자동으로 조정하여 전체 프로젝트의 코드 스타일을 통일합니다.

4. 설정 파일 상세

프로젝트 루트 디렉토리에 pyproject.toml을 만들어 Ruff를 설정합니다:

TOML
[tool.ruff]
# 대상 Python 버전
target-version = "py312"
# 줄 길이 제한
line-length = 88
# 검사할 디렉토리
src = ["src", "tests"]
# 제외할 디렉토리
exclude = [
    ".git",
    ".venv",
    "__pycache__",
    "build",
    "dist",
]

[tool.ruff.lint]
# 활성화할 규칙 집합
select = [
    "E",      # pycodestyle 오류
    "W",      # pycodestyle 경고
    "F",      # pyflakes
    "I",      # isort (import 정렬)
    "UP",     # pyupgrade (버전 업그레이드 권장)
    "B",      # flake8-bugbear (일반적인 버그 패턴)
    "SIM",    # flake8-simplify (코드 단순화)
    "RUF",    # Ruff 자체 규칙
]
# 무시할 규칙
ignore = [
    "E501",   # 줄이 너무 김 (formatter에 맡김)
    "E402",   # import가 파일 상단에 없음 (일부 스크립트에서 필요)
]
# 허용할 최대 복잡도
mccabe.max-complexity = 10

[tool.ruff.lint.per-file-ignores]
# 테스트 파일에서 일부 규칙 무시
"tests/**/*.py" = ["S101", "PLR2004"]
# 마이그레이션 파일에서 모든 규칙 무시
"**/migrations/*.py" = ["ALL"]

[tool.ruff.format]
# 따옴표 스타일: 홑따옴표 또는 쌍따옴표
quote-style = "double"
# 들여쓰기 타입
indent-style = "space"
# 파일末尾 개행
skip-magic-trailing-comma = false

4.1 주요 규칙 집합 설명

규칙 집합 설명 대표 규칙
E/W pycodestyle 스타일 검사 E501 줄이 너무 김, W292 파일末尾 개행 누락
F pyflakes 오류 감지 F401 미사용 import, F841 미사용 변수
I import 정렬 I001 import 순서 부정확
UP Python 버전 업그레이드 UP006 typing.List 대신 list 사용
B bugbear 일반적인 버그 B006 가변 기본 인수, B007 미사용 루프 변수
SIM 코드 단순화 SIM101 중복 isinstance, SIM108 삼항 표현식 사용
RUF Ruff 고유 규칙 RUF001 모호한 문자, RUF005 결합 대신 전개

5. Black/isort/Flake8 완전 마이그레이션 가이드

기존에 Black + isort + Flake8 조합을 사용 중이었다면 Ruff로 완전히 전환할 수 있습니다.

5.1 기존 도구 제거

BASH
pip uninstall black isort flake8 autoflake pyupgrade -y

5.2 Ruff를 Black과 호환되게 설정

pyproject.toml에 Black과 호환되는 설정을 추가합니다:

TOML
[tool.ruff]
line-length = 88          # Black 기본 줄 너비
target-version = "py312"

[tool.ruff.format]
quote-style = "double"    # Black 기본 쌍따옴표
indent-style = "space"

[tool.ruff.lint]
select = ["E", "W", "F", "I"]

5.3 전체 프로젝트 일괄 수정

BASH
# 1단계: 모든 Python 파일 포매팅
ruff format .

# 2단계: 검사 및 자동 수정
ruff check --fix .

# 3단계: 남은 문제 확인 (자동 수정 안 함)
ruff check .

5.4 pre-commit과 통합

.pre-commit-config.yaml을 생성합니다:

YAML
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.9.0
    hooks:
      # 먼저 포매팅
      - id: ruff-format
      # 그다음 검사
      - id: ruff
        args: [--fix, --exit-non-zero-on-fix]

pre-commit hook을 설치합니다:

BASH
pip install pre-commit
pre-commit install

이제 git commit할 때마다 Ruff가 자동으로 스테이징된 파일을 포매팅하고 검사합니다.

6. CI/CD 통합 실전

6.1 GitHub Actions

YAML
name: Ruff Check

on: [push, pull_request]

jobs:
  ruff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install Ruff
        run: pip install ruff

      - name: Run Ruff format check
        run: ruff format --check .

      - name: Run Ruff lint
        run: ruff check --output-format=github .

6.2 GitLab CI

YAML
ruff:
  image: python:3.12-slim
  stage: test
  script:
    - pip install ruff
    - ruff format --check .
    - ruff check .
  allow_failure: true  # 초기에는 실패 허용 가능

6.3 대형 프로젝트에서 성능 최적화

초대형 프로젝트에서는 다음 최적화 전략을 활용할 수 있습니다:

BASH
# 변경된 파일만 검사 (CI 시나리오)
ruff check --diff .

# SARIF 형식 출력 (GitHub Code Scanning용)
ruff check --output-format=sarif . > results.sarif

# 특정 규칙만 검사
ruff check --select=F,E .

# Ruff 설정 및 캐시 상태 확인
ruff check --show-settings .

7. Ruff vs 경쟁 도구 비교

기능 Ruff Flake8 Black + isort
언어 Rust Python Python
속도 ⚡ 매우 빠름 (밀리초 단위) 느림 (초 단위) 중간
기능 범위 Linter + Formatter Linter만 Formatter만
플러그인 생태계 내장 규칙 풍부한 플러그인 플러그인 확장
자동 수정 ✅ 지원 ❌ 미지원 ✅ 지원
설정 방식 pyproject.toml .flake8/.cfg pyproject.toml
Python 의존성 Python 불필요 필요 필요

성능实测

50만 줄 코드 프로젝트에서:

  • Ruff check: 0.3초
  • Flake8: 45초
  • pylint: 120초

Ruff는 Flake8보다 약 150배, pylint보다 약 400배 빠릅니다.

8. 고급 활용법

8.1 사용자 정의 규칙

Ruff는 pyproject.toml을 통해 규칙의 심각도 수준을 사용자 정의할 수 있습니다:

TOML
[tool.ruff.lint]
select = ["E", "F", "W"]

# 일부 규칙을 오류가 아닌 경고로 설정
[tool.ruff.lint.flake8-errmsg]
max-string-length = 20

[tool.ruff.lint.pydocstyle]
convention = "google"  # 또는 "numpy", "pep257"

8.2 IDE와 통합

VS Code: 공식 Ruff 확장을 설치하면 다음을 지원합니다: - 실시간 lint 검사 - 저장 시 자동 포매팅 - 권장 사항 원클릭 수정

JSON
// .vscode/settings.json
{
  "[python]": {
    "editor.defaultFormatter": "charliermarsh.ruff",
    "editor.codeActionsOnSave": {
      "source.fixAll.ruff": "explicit"
    }
  }
}

PyCharm: External Tools를 통해 설정합니다: - Settings → Tools → External Tools 열기 - Ruff 추가: Program을 ruff로, Arguments를 check --fix $FilePath$로 설정

8.3 증분 검사 (Watch 모드)

BASH
# 파일 변경 감지, 자동 재검사
ruff check --watch .

8.4 HTML 보고서 생성

BASH
# JSON 형식 출력, jq로 처리 가능
ruff check --output-format=json . | jq '.'

# 또는 sarif 형식으로 GitHub Code Scanning과 연동
ruff check --output-format=sarif . > ruff-results.sarif

9. 자주 묻는 질문

Q1: Ruff로 Flake8를 완전히 대체할 수 있나요?

대부분의 경우 가능합니다. Ruff에는 Flake8의 대부분 규칙(E, W, F 계열)과 인기 플러그인의 규칙(bugbear, eradicate 등)이 내장되어 있습니다. 하지만 매우 특화된 Flake8 플러그인을 사용 중이라면 Ruff에 대응 구현이 있는지 확인이 필요합니다.

Q2: Ruff로 pylint를 대체할 수 있나요?

완전히 대체하기는 어렵습니다. Ruff는 코드 스타일과 일반적인 버그 감지에 중점을 두는 반면, pylint는 더 심층적인 코드 품질 분석(복잡도 점수, 중복 코드 감지 등)을 제공합니다. 일상 개발에서는 Ruff면 충분하지만, 엄격한 품질 감사가 필요하면 Ruff + pylint를 함께 사용할 수 있습니다.

Q3: Ruff의 --fix는 안전한가요?

매우 안전합니다. Ruff의 자동 수정은 명확한 수정 전략이 있는 규칙에만 적용되며, 의미론적 변경은 하지 않습니다. 수정 전에는 ruff check --diff .로 변경 사항을 미리 확인하는 것을 권장합니다.

Q4: Ruff는 어떤 Python 버전을 지원하나요?

Ruff 자체는 Python 3.7 ~ 3.13 코드의 검사를 지원합니다. target-version을 설정하면 대상 Python 버전을 지정하고相应하는 업그레이드 권장 사항을 받을 수 있습니다.

10. 요약

Ruff는 Python 생태계의 코드 품질 인프라로 자리 잡고 있습니다. Rust가 가져온 극致的인 성능, 풍부한 내장 규칙, 그리고 올인원 linter + formatter 경험으로 Python 프로젝트의 코드 품질 관리를 전례 없이 간단하고 효율적으로 만들었습니다.

액션 권장 사항:

  1. pip install ruff로 설치
  2. 프로젝트에서 ruff check --fix . + ruff format . 실행
  3. pyproject.toml로 사용자 규칙 설정
  4. pre-commit 및 CI/CD 파이프라인에 통합

프로젝트의 코드 품질이 즉시 크게 향상될 것이며, 전체 과정은 몇 분이면 충분합니다.


관련 링크: