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는 왜 이렇게 빠를까?
- Rust 컴파일: Rust의 성능은 Python을 압도합니다. 파싱 속도에서桁수 차이가 납니다.
- 병렬 처리: 멀티코어 CPU를 자동으로 활용해 파일을 병렬로 스캔합니다.
- 제로 의존성: Python 런타임이 필요 없습니다. 단일 바이너리 파일로 실행됩니다.
- 증분 캐시: 변경된 파일만 검사하므로 두 번째 실행은 거의 순간적으로 완료됩니다.
Ruff GitHub 저장소: https://github.com/astral-sh/ruff ⭐ 2026년 기준 35,000개 이상의 Star를 돌파했습니다.
2. Ruff 설치
Ruff는 다양한 방법으로 설치할 수 있으며, pip 또는 공식 설치 스크립트를 권장합니다:
# 방법 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를 만들어 보세요:
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 코드 검사 실행
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 자동 수정
ruff check --fix hello.py
실행 후 파일이 자동으로 수정됩니다:
def hello_world():
x = 1 + 2
print("hello world")
return x
if __name__ == "__main__":
hello_world()
3.3 코드 포매팅
ruff format hello.py
ruff format은 Black과 유사하게 들여쓰기, 빈 줄, 따옴표 스타일 등을 자동으로 조정하여 전체 프로젝트의 코드 스타일을 통일합니다.
4. 설정 파일 상세
프로젝트 루트 디렉토리에 pyproject.toml을 만들어 Ruff를 설정합니다:
[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 기존 도구 제거
pip uninstall black isort flake8 autoflake pyupgrade -y
5.2 Ruff를 Black과 호환되게 설정
pyproject.toml에 Black과 호환되는 설정을 추가합니다:
[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 전체 프로젝트 일괄 수정
# 1단계: 모든 Python 파일 포매팅
ruff format .
# 2단계: 검사 및 자동 수정
ruff check --fix .
# 3단계: 남은 문제 확인 (자동 수정 안 함)
ruff check .
5.4 pre-commit과 통합
.pre-commit-config.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을 설치합니다:
pip install pre-commit
pre-commit install
이제 git commit할 때마다 Ruff가 자동으로 스테이징된 파일을 포매팅하고 검사합니다.
6. CI/CD 통합 실전
6.1 GitHub Actions
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
ruff:
image: python:3.12-slim
stage: test
script:
- pip install ruff
- ruff format --check .
- ruff check .
allow_failure: true # 초기에는 실패 허용 가능
6.3 대형 프로젝트에서 성능 최적화
초대형 프로젝트에서는 다음 최적화 전략을 활용할 수 있습니다:
# 변경된 파일만 검사 (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을 통해 규칙의 심각도 수준을 사용자 정의할 수 있습니다:
[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 검사 - 저장 시 자동 포매팅 - 권장 사항 원클릭 수정
// .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 모드)
# 파일 변경 감지, 자동 재검사
ruff check --watch .
8.4 HTML 보고서 생성
# 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 프로젝트의 코드 품질 관리를 전례 없이 간단하고 효율적으로 만들었습니다.
액션 권장 사항:
pip install ruff로 설치- 프로젝트에서
ruff check --fix .+ruff format .실행 pyproject.toml로 사용자 규칙 설정- pre-commit 및 CI/CD 파이프라인에 통합
프로젝트의 코드 품질이 즉시 크게 향상될 것이며, 전체 과정은 몇 분이면 충분합니다.
관련 링크:
- Ruff 공식 문서: https://docs.astral.sh/ruff/
- Ruff GitHub: https://github.com/astral-sh/ruff
- uv 도구 (Ruff 동일 팀): https://docs.astral.sh/uv/
- 관련 자료: linux-tutorials/linux-fileformat.md — Python 파일 포매팅 이해
- 관련 자료: linux-tutorials/ubuntu-dependency.md — Python 패키지 관리 기초