LabHub

블로그

2026년의 포매터·린터 — Biome, dprint, Ruff, oxc, Prettier 4, ESLint v9의 진짜 위치

한국어English日本語

프롤로그 — 왜 또 포매터·린터 이야기인가

prettier --write . 한 줄로 끝나던 시대가 있었다. 2020년쯤이다. 그 후 5년이 지나는 동안 같은 명령이 모노레포에서 30초, CI에서 2분으로 부풀었다. eslint --max-warnings 0 은 그것보다 더 느렸고, 어느 순간 우리는 "사전 커밋 훅에서 lint를 빼야 하나"를 진지하게 토론하고 있었다.

같은 시기 Python 진영에서도 비슷한 통증이 있었다. black + flake8 + isort + pylint 4단 콤보는 안정적이지만 느렸다. 큰 저장소에서 한 번 돌리는 데 분 단위가 걸렸고, 4개 도구의 설정 파일이 따로 놀았다.

여기에 Rust 진영의 도구 작성자들이 답을 들고 왔다. 속도가 진짜 100배 빠르면 다른 모든 것이 달라진다는 답이었다. Ruff(2022)가 Python에서 그걸 증명했고, Biome(이전의 Rome)이 JS/TS에서 같은 길을 갔다. dprint, oxc, ty(타입 체커), uv(패키지 매니저)까지 — Astral과 Biome 팀, 그리고 Boshen(oxc) 같은 작은 팀들이 이끄는 Rust 재작성의 물결이다.

2026년 현재, Prettier 4가 Rust 플러그인 길을 공식적으로 받아들였고, ESLint v9의 flat config가 안정화됐으며, typescript-eslint v8는 단일 패키지로 다시 묶였다. Biome 2는 multi-file 분석과 import sorting을 정식 기능으로 갖췄고, Ruff는 사실상 Python 린팅의 기본값이 됐다.

이 글은 그 지형을 정리한다. 어느 도구가 어느 자리에서 무엇을 잘하는가, "Rust로 다시 짜면 다 좋아진다"는 명제가 어디까지 진실인가, 그리고 우리 팀에 무엇이 맞는가. 마케팅이 아니라 측정 가능한 트레이드오프로.

핵심 한 줄: 도구는 빨라졌고 통합됐다. 하지만 "Biome 한 줄로 다 해결" 같은 단순한 그림은 아직 아니다. 어떤 트레이드오프를 받아들이느냐가 선택을 결정한다.


1장 · 지형도 — 2026년의 포매터·린터 전체 그림

먼저 큰 그림을 그린다. 언어별로 어떤 선택지가 있고, 누가 어디서 잘 도느냐.

언어 / 영역전통적 도구2026년 주력차세대 후보
JS / TSPrettier + ESLintPrettier + ESLint v9, Biome 2oxc, dprint
Pythonblack + flake8 + isort + pylintRuff (format + lint)ty (타입 체커)
Rustrustfmt + clippyrustfmt + clippy— (이미 Rust)
Gogofmt + golangci-lint동일
CSS / SCSSPrettier + stylelintPrettier + stylelint, Biome 2dprint, oxc
MarkdownPrettier, remark-lintPrettier, dprint
TOML / YAML / JSONPrettierdprint, taplo, yamlfmt
다중 언어 모노레포Prettier + ESLintdprint(통합 포매터), Biome

카테고리별 한 줄 정리

이 글의 주인공은 세 번째 흐름 — Rust로 짜인 차세대 통합 도구들. 그 도구들이 기존 도구를 대체하는 곳, 보완하는 곳, 아직 못 가는 곳을 본다.

한 줄 요약: 언어마다 사정이 다르다. Python은 Ruff가 사실상 정답이 됐고, JS/TS는 아직 Biome vs Prettier+ESLint의 결정이 남아 있고, 모노레포는 dprint가 새로운 선택지로 들어왔다.


2장 · Rust 재작성 패턴 — 왜 10~100배 빠른가

먼저 "왜 빠른가"를 짚는다. 마케팅이 아니라 구조의 차이다.

측정 가능한 속도 차

Biome 공식 문서가 보여주는 수치 — 단일 파일 포맷에서 Biome은 Prettier보다 25배~35배 빠르고, 큰 저장소에서 더 큰 격차가 난다. Ruff는 같은 규칙으로 flake8 대비 약 100배 빠른 것이 자주 보고된다(중간~큰 Python 저장소에서 분 단위가 초 단위로).

실제 사용 보고에서 자주 보이는 수치:

왜 이 정도 차이가 나나

  1. 언어 자체의 차 — JS 도구는 V8 JIT 위에서 도는 인터프리터 코드, Rust 도구는 네이티브 바이너리. 이것만으로도 3~10배
  2. 단일 패스 파싱 — 전통 도구는 lex→parse→AST 변환을 여러 번 한다. Biome/oxc/Ruff는 한 번의 패스로 lossless concrete syntax tree(CST)를 만들고 모든 분석에 재사용
  3. 병렬화 — Rust의 데이터 동시성을 살려 파일을 진짜 병렬로 처리. JS 도구는 단일 스레드, Worker 풀을 쓰더라도 직렬화 비용
  4. 메모리 레이아웃 — CST 노드를 cache-friendly한 배열에 저장(rowan/oxc-resolver 같은 라이브러리). Allocation이 적음
  5. 재시작 비용 없음 — Rust 바이너리는 시작이 1~5ms, Node는 50~200ms. CLI 반복 호출에서 큰 차이

빠름의 2차 효과

한 줄 요약: 빠름 자체보다 빠름이 가능하게 하는 워크플로 변화가 본질이다. "어차피 느려서 못 함"이 풀린다.


3장 · Biome 2 — 포매터·린터 통합의 선두

Biome은 가장 야심적인 통합 도구다. 원래 이름은 Rome(2020, Sebastian McKenzie — Babel 만든 사람), 자금 부족으로 정지, 2023년 커뮤니티 포크로 Biome 출범, 2024년 Biome 1.0, 2025년 Biome 2.0.

Biome 2의 핵심 약속

설정 예시

{
  "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
  "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
  "files": { "ignoreUnknown": true },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100
  },
  "javascript": {
    "formatter": { "quoteStyle": "single", "semicolons": "asNeeded" }
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": { "noUnusedVariables": "error" },
      "style": { "useImportType": "warn" },
      "suspicious": { "noExplicitAny": "warn" }
    }
  },
  "assist": {
    "enabled": true,
    "actions": { "source": { "organizeImports": "on" } }
  }
}

Biome가 잘하는 곳

Biome가 못 가는 곳 / 아직 부족한 곳

결정 기준

팀 상황Biome 적합도
새 JS/TS 프로젝트, 단순 규칙매우 높음
모노레포, CI 속도 중요, Vue/Svelte 없음높음
기존 Prettier+ESLint, 만족 중옮길 동기 약함
eslint-plugin-* 깊이 활용아직 어려움
Vue / Svelte / Astro / MDX 비중 큼추천 안 함

한 줄 요약: Biome는 "JS/TS만 보면" 가장 매력적인 통합 도구다. 단, 플러그인 생태계와 비표준 파일 지원에서 Prettier+ESLint를 완전히 대체하기에는 아직 빈자리가 있다.


4장 · dprint — 플러그인 기반 다중 언어 포매터

dprint는 다른 접근이다. 자체적으로는 작은 코어, 언어별 플러그인으로 확장한다. 단일 도구로 JS/TS, JSON, Markdown, TOML, Dockerfile, SQL을 한 번에 포맷한다.

dprint의 차별점

설정 예시

{
  "lineWidth": 100,
  "indentWidth": 2,
  "useTabs": false,
  "typescript": {
    "quoteStyle": "preferSingle",
    "semiColons": "asi"
  },
  "json": {
    "lineWidth": 200
  },
  "markdown": {
    "textWrap": "always"
  },
  "toml": {},
  "dockerfile": {},
  "plugins": [
    "https://plugins.dprint.dev/typescript-0.93.0.wasm",
    "https://plugins.dprint.dev/json-0.20.0.wasm",
    "https://plugins.dprint.dev/markdown-0.18.0.wasm",
    "https://plugins.dprint.dev/toml-0.7.1.wasm",
    "https://plugins.dprint.dev/dockerfile-0.3.4.wasm"
  ],
  "includes": ["**/*.{ts,tsx,js,jsx,json,md,toml,Dockerfile}"],
  "excludes": ["**/node_modules", "**/dist"]
}

dprint가 잘하는 곳

dprint가 못 가는 곳

누가 쓰나

한 줄 요약: dprint는 "한 도구로 모든 텍스트 포맷"을 노린다. 린팅 없이 포맷만, 다중 언어가 진짜로 섞인 모노레포에서 빛난다.


5장 · Ruff — Python을 평정한 Rust 도구

Ruff는 가장 압도적인 성공 사례다. Charlie Marsh(Astral)가 2022년 첫 릴리스, 2026년 현재 PyPI Python 도구 다운로드 통계에서 사실상 1위. Django, Pandas, FastAPI, Pydantic, Apache Airflow, scikit-learn 같은 메이저 프로젝트가 Ruff를 채택했다.

Ruff의 약속

설정 예시

[tool.ruff]
line-length = 100
target-version = "py312"
extend-exclude = ["migrations", ".venv", "build"]

[tool.ruff.lint]
select = [
  "E", "W",      # pycodestyle
  "F",           # pyflakes
  "I",           # isort
  "N",           # pep8-naming
  "UP",          # pyupgrade
  "B",           # flake8-bugbear
  "C4",          # flake8-comprehensions
  "DTZ",         # flake8-datetimez
  "S",           # flake8-bandit (security)
  "RUF",         # ruff-specific
]
ignore = ["E501"]  # line-too-long handled by formatter
fixable = ["ALL"]
unfixable = []

[tool.ruff.lint.per-file-ignores]
"tests/*" = ["S101"]  # allow assert in tests
"__init__.py" = ["F401"]  # allow unused imports

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

Ruff가 잘하는 곳 — 거의 모든 곳

Ruff의 한계 / 차이

Astral의 큰 그림 — Rust 재작성 전체 스택

Charlie Marsh의 야심은 Ruff에 그치지 않는다. Astral은 Python 도구 체인 전체를 Rust로 다시 쓰고 있다.

도구대체 대상상태(2026)
Ruffflake8, isort, black, pydocstyle, ...안정, 광범위 채택
uvpip, virtualenv, pip-tools, pipx, poetry(일부)안정, 빠르게 확산
tymypy, pyright(부분)알파/베타
ryepoetry, hatch(개념적)uv에 흡수되는 중

전체 패턴: "도구 하나가 빠르면 그 도구 위주로 모든 워크플로가 재편된다." 같은 패턴이 Biome(JS), oxc(JS)에서 반복된다.

한 줄 요약: Ruff는 Python 도구 체인에서 사실상 디폴트가 됐다. 이유는 단순하다 — 빠르고, 통합돼 있고, 마이그레이션 비용이 낮다.


6장 · oxc — Rust JavaScript 도구 체인 가족

oxc는 다른 야심이다. Boshen이 이끄는 프로젝트로, JavaScript 도구 체인 전체를 Rust로 만든다. 파서, 리졸버, 트랜스포머, 린터, 포매터, 미니파이어. Biome는 "단일 사용자 도구"라면, oxc는 "다른 도구가 쓰는 컴포넌트 라이브러리"에 가깝다.

oxc의 구성 요소

컴포넌트무엇비교 대상
oxc-parserJS/TS 파서acorn, esprima, swc 파서
oxc-resolver모듈 해석enhanced-resolve
oxc-transformerJS/TS 변환Babel, swc
oxlint린터ESLint
oxc-prettier포매터(Prettier Rust 포트)Prettier
oxc-minifier미니파이어terser, swc, esbuild

oxlint — ESLint를 노린 Rust 린터

oxlint는 ESLint 코어 규칙과 플러그인 일부를 Rust로 다시 쓴다. 2026년 현재 oxlint는 ESLint v9 호환 모드를 일부 지원하며, 빠른 사전 점검(pre-flight check) 용도로 권장된다.

# 빠른 lint (oxlint), 깊은 lint (ESLint)
oxlint --deny-warnings src/
# ESLint 호환 보고
oxlint --rules-include=react-hooks src/

oxc가 잘하는 곳

oxc의 한계

Biome vs oxc — 무엇이 다른가

비교Biomeoxc
목표통합 사용자 도구컴포넌트 라이브러리 + 도구 가족
단일 설정그렇다 (biome.json)도구마다 다름
사용자 경험"Prettier+ESLint 대체""ESLint 빠른 보완"
플러그인내장 위주(계획) WASM 플러그인
누가 채용애플리케이션 팀빌드 도구 작성자, 프레임워크

한 줄 요약: Biome가 사용자 도구, oxc는 컴포넌트 가족. 사용자 입장에서는 Biome가 직관적, 도구 작성자 입장에서는 oxc가 유용. 둘은 경쟁이 아니라 다른 층위에서 일한다.


7장 · Prettier 4 — 황제는 어떻게 응답했는가

Prettier는 2017년 이후 사실상 JS/TS 포매터의 디폴트였다. 의견을 가지고 강제하고, 설정이 거의 없는 것이 핵심 철학. 그 결과 거의 모든 프로젝트가 채택했다.

하지만 속도 문제가 누적됐다. Prettier 3까지는 순수 JS, Node 위에서 도는 도구. 빠른 도구들과의 격차가 커지자, Prettier 팀은 2025년부터 Rust 플러그인 경로를 공식화했다.

Prettier 4의 핵심 변화

설정 예시 (Prettier 4)

{
  "experimentalRustBackend": true,
  "printWidth": 100,
  "singleQuote": true,
  "semi": false,
  "trailingComma": "all",
  "plugins": [
    "prettier-plugin-tailwindcss",
    "prettier-plugin-organize-imports"
  ]
}

Prettier가 살아남는 이유

Prettier vs Biome — 2026년의 결정

기준Prettier 4Biome 2
JS/TS 포맷 속도5~15배 가속(Rust 백엔드)25~35배 가속
린터 통합없음 (ESLint 별도)통합
플러그인 생태계거대작음
비표준 파일 지원넓음좁음
단일 설정부분(여전히 .prettierrc + .eslintrc)완전(biome.json)
마이그레이션 비용없음(이미 쓰고 있음)중간 (biome migrate)

한 줄 요약: Prettier는 죽지 않는다 — 생태계가 너무 깊다. Rust 백엔드로 속도 격차를 좁히고, ESLint와의 조합으로 살아남는다. Biome는 "통합의 가치"가 큰 새 프로젝트에서 강하다.


8장 · ESLint v9와 typescript-eslint v8 — flat config 시대

ESLint 진영도 가만히 있지 않았다.

ESLint v9의 변화

flat config 예시

// eslint.config.js
import js from '@eslint/js'
import tseslint from 'typescript-eslint'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'

export default tseslint.config(
  { ignores: ['dist', 'build', '.next'] },
  js.configs.recommended,
  ...tseslint.configs.recommendedTypeChecked,
  {
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
    plugins: {
      'react-hooks': reactHooks,
      'react-refresh': reactRefresh,
    },
    rules: {
      ...reactHooks.configs.recommended.rules,
      'react-refresh/only-export-components': 'warn',
      '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
    },
  }
)

typescript-eslint v8 — 단일 패키지

v7 이전에는 @typescript-eslint/parser@typescript-eslint/eslint-plugin을 따로 설치해야 했다. v8에서는 typescript-eslint 단일 패키지로 통합. 설정도 더 짧아짐.

npm i -D typescript-eslint

projectService 기능 — 타입 인식 lint의 비용 절감

타입 인식 lint(@typescript-eslint/recommended-type-checked)는 정확하지만 느렸다. v8의 projectService는 TypeScript LSP처럼 동작 — tsconfig를 자동 발견하고, 파일 단위로 타입 정보를 lazy로 로드. 모노레포에서 lint 속도를 2~5배 개선.

ESLint가 살아남는 이유

ESLint와 Biome의 공존 패턴

많은 팀이 이렇게 한다:

포맷:  Prettier (또는 Biome format)
빠른 린트: oxlint / Biome lint (사전 커밋, 즉시 피드백)
깊은 린트: ESLint (CI, 타입 인식 + 플러그인)

ESLint를 버리는 게 아니라 "빠른 1차 통과 + 깊은 2차 통과"로 분리. Biome+ESLint 같이 도는 게 어색해 보이지만 실제로 잘 작동한다.

한 줄 요약: ESLint는 v9 flat config로 정리됐고, typescript-eslint v8의 projectService로 속도도 개선됐다. 플러그인 생태계 덕에 가까운 시일 안에 죽지 않는다.


9장 · stylelint와 CSS 도구들

CSS 진영도 비슷한 흐름이다.

stylelint v16

CSS 포맷 — 누가 잘하나

도구CSSSCSSLessTailwind 클래스 정렬
Prettier안정안정안정플러그인으로
Biome안정부분(2.x)미지원미지원(직접)
dprint베타 플러그인베타미지원미지원

결정 가이드

한 줄 요약: CSS는 아직 Prettier + stylelint 조합이 가장 안전하다. Biome 2가 빠르게 따라잡지만 SCSS·Tailwind 통합은 시간이 더 필요하다.


10장 · 비교 매트릭스 — 한눈에 보는 2026

항목Prettier 4Biome 2dprintRuffoxlintESLint v9stylelint v16
언어JS/TS/CSS/MD/YAML/JSON/Vue/Svelte/AstroJS/TS/JSX/JSON/CSS/GraphQLJS/TS/JSON/MD/TOML/DockerfilePythonJS/TSJS/TSCSS/SCSS/Less
포매터있음있음있음(코어)있음없음없음(deprecated)없음
린터없음있음없음있음있음있음있음
구현 언어JS + Rust(v4)RustRust + WASMRustRustJSJS
속도(상대)1배 (v4 Rust 5~15배)25~35배10~30배50~100배50~80배1배1배
단일 설정부분완전완전(포맷만)완전부분부분부분
플러그인 생태계거대작음중간없음(내장)작음거대거대
자동 수정포맷만포맷 + 일부 lint포맷만광범위일부광범위일부
에디터 통합최고좋음좋음최고좋음최고좋음
도입 비용(기존팀)없음(이미 씀)중간중간낮음낮음(보완)없음(이미 씀)없음
추천 사용처모든 JS/TS, 폭넓은 파일 포맷JS/TS 통합, 속도 우선다중 언어 모노레포Python 거의 모든 곳빠른 1차 lint깊은 lint, 플러그인 활용CSS 모든 곳

한 줄 정리


11장 · 마이그레이션 — 실제 시나리오 3개

시나리오 A · Prettier + ESLint → Biome 2 (Next.js 모노레포)

# 1. Biome 설치 및 초기화
npm i -D --save-exact @biomejs/biome
npx biome init

# 2. Prettier 설정 마이그레이션
npx biome migrate prettier --write
# 3. ESLint 설정 마이그레이션 (가능한 부분만)
npx biome migrate eslint --write

# 4. 첫 포맷 (큰 diff 한 번)
npx biome format --write .

# 5. 린트 점검
npx biome lint .

# 6. CI / package.json 스크립트 변경
# "lint": "biome lint .",
# "format": "biome format --write ."

현장 보고:

옮기지 말아야 할 신호:

시나리오 B · black + flake8 + isort → Ruff (Django 모노레포)

# pyproject.toml
[tool.ruff]
line-length = 100
target-version = "py312"

[tool.ruff.lint]
extend-select = ["E", "W", "F", "I", "B", "UP", "DTZ", "S", "RUF"]
ignore = ["E501"]

[tool.ruff.format]
quote-style = "double"
# 1. 설치
uv add --dev ruff

# 2. pyproject.toml 설정
# (위와 같이 작성)

# 3. 첫 포맷 (black과 95% 일치, diff 한 번)
ruff format .

# 4. 린트 + 자동 수정
ruff check --fix --unsafe-fixes .

# 5. pre-commit 훅 단순화
# - id: ruff
#   args: [--fix]
# - id: ruff-format
# (이전에는 black, flake8, isort, pyupgrade, autoflake 5개)

현장 보고:

옮기지 말아야 할 신호: 거의 없다. Python에서는 Ruff가 사실상 디폴트.

시나리오 C · 다중 언어 모노레포 → dprint + Biome + Ruff (혼합)

큰 회사의 모노레포에는 TS, Python, Markdown, TOML, Dockerfile, K8s YAML이 같이 산다. 한 도구로 다 못 하면 도구를 분업.

포맷:
  TS / JS / JSON / CSS  → Biome format
  Python                  → Ruff format
  Markdown / TOML / Dockerfile → dprint

린트:
  TS / JS               → Biome lint (빠른) + ESLint (CI, 깊음)
  Python                → Ruff
  CSS                   → stylelint

CI 통합:
  단계 1: dprint check + biome check + ruff check (모두 5~10초)
  단계 2: ESLint --max-warnings 0 (CI에서만, 1~2분)
  단계 3: 타입 체크 (tsc, mypy/ty)

현장 보고: 도구가 3개가 되지만 각 도구가 잘하는 곳에 둠. 사전 커밋 훅은 빠른 도구들만, 깊은 점검은 CI.

한 줄 요약: 마이그레이션은 한 번에 다 옮기지 않아도 된다. 빠른 도구가 잘하는 곳부터 점진적으로, 기존 도구는 깊은 검증으로 남기는 패턴이 가장 안전하다.


12장 · 안티패턴과 함정

빠른 도구를 도입할 때 자주 만나는 함정들.

"Biome 한 줄로 다 해결될 거다"

"Ruff format이 black과 100% 동일"

"Prettier를 빼면 에디터가 불편해진다"

"Rust 도구는 항상 빠르니까 캐싱 필요 없다"

"린터가 빠르니까 규칙을 다 켜자"

"사전 커밋 훅에 모든 걸 다 넣자"

"Biome migrate가 완벽할 거다"

"단일 도구 = 단일 진실"

"Rust 백엔드 = 무조건 빠름"

"포매터·린터를 통합하면 의견이 충돌하지 않는다"


13장 · 의사결정 트리 — 우리 팀은 무엇을 골라야 하나

시작:
├─ 언어가 Python인가?
│   └─ 예 → Ruff (거의 모든 경우). mypy/ty는 별도
├─ JS/TS 위주인가?
│   │
│   ├─ 새 프로젝트, 단순 규칙, 속도 우선
│   │   └─ Biome 2 단독
│   │
│   ├─ 기존 Prettier+ESLint, 만족, 속도 불만 없음
│   │   └─ 그대로 유지 (Prettier 4 Rust 백엔드 옵션 활성)
│   │
│   ├─ 기존 Prettier+ESLint, 속도 진짜 문제
│   │   ├─ 플러그인 깊게 활용 → Prettier + Biome lint(빠른 1차) + ESLint(깊은)
│   │   └─ 플러그인 적음 → Biome 2로 마이그레이션
│   │
│   ├─ Vue / Svelte / Astro 비중 큼
│   │   └─ Prettier 유지 (Biome 미지원 영역)
│   │
│   └─ 빠른 사전 점검 추가
│       └─ oxlint를 husky 사전 커밋에
├─ 다중 언어 모노레포(TS + Python + 인프라)
│   └─ 도구 분업:
│      - TS → Biome 또는 Prettier
│      - Python → Ruff
│      - 인프라(TOML, Dockerfile, MD) → dprint
├─ CSS / Tailwind 중심
│   └─ Prettier + prettier-plugin-tailwindcss + stylelint
└─ 모노레포 전체 lint가 분 단위
    └─ 1차 빠른 통과 도입:
       - Biome / Ruff / oxlint를 husky 사전 커밋과 CI 첫 단계로
       - 기존 도구는 CI 후반에 깊은 점검 용도로

단순 규칙


에필로그 — 체크리스트, 안티패턴, 다음 글 예고

2026년의 포매터·린터 지형은 5년 전과 다르다. Rust 재작성의 물결로 도구가 10~100배 빨라졌고, "포매터가 린터를 흡수한다"는 통합 흐름이 본격화됐다. Biome 2와 Ruff가 각자의 영역에서 사실상 표준에 가까워졌고, Prettier 4는 Rust 백엔드로 응답했고, ESLint v9는 flat config로 자기 자리를 정리했다.

하지만 "한 도구로 모든 게 끝"이라는 그림은 아직 아니다. 플러그인 생태계, 비표준 파일 지원, type-aware 분석 같은 영역에서 기존 도구가 살아남는다. 우리 팀에 맞는 선택은 — 무엇이 진짜 병목이고, 어떤 트레이드오프를 받아들일지 — 측정에서 시작한다.

도구 선택 체크리스트

  1. 현재 lint·포맷 시간이 진짜로 문제인가? — 30초가 1초가 되어 무엇이 달라지나 측정
  2. 언어별 사정은 다른가? — Python은 Ruff가 거의 결정, JS/TS는 더 복잡
  3. 플러그인 의존이 깊은가? — eslint-plugin-* 깊게 쓰면 ESLint 유지가 안전
  4. 모노레포 / 다중 언어 / 비표준 파일? — dprint 또는 도구 분업 검토
  5. 마이그레이션 한 번에 vs 점진? — 큰 PR은 별도 마이그레이션 PR로
  6. 사전 커밋 vs CI 분리 — 빠른 도구만 사전 커밋에, 깊은 도구는 CI에
  7. type-aware 린트가 필요한가?no-floating-promises 류는 typescript-eslint 유지
  8. 에디터 통합이 되는가? — VS Code / JetBrains 익스텐션 성숙도 확인
  9. CI에서 도구 캐싱이 되는가? — 빠른 도구도 다운로드 단계 캐싱 필요
  10. 팀 합의가 있는가? — 일부만 Biome 쓰면 commit 충돌

안티패턴

안티패턴왜 나쁜가대신
Biome 한 줄로 ESLint 완전 제거type-aware 규칙, 플러그인 부재빠른 lint + 깊은 lint 분리
Ruff format이 black과 100% 같다고 가정95% 일치, 엣지 케이스 diff마이그레이션 PR 별도
모든 규칙을 켜기 (ALL)false positive 폭발, 무시 시작recommended에서 시작, 필요한 것만
사전 커밋에 모든 검사커밋 1분, --no-verify 우회빠른 것만 사전 커밋, 깊은 건 CI
Rust 도구는 캐싱 불필요다운로드 단계가 30초~1분바이너리 / 플러그인 캐싱
Biome migrate 후 검토 없음매핑 안 된 규칙 손실diff 사람 리뷰
단일 도구 강제, 팀 합의 없음일부만 도입, diff 충돌합의 후 lockfile / 익스텐션 권장
마이크로 벤치마크만 보고 결정실제 워크플로와 다름모노레포 전체 시간 측정
포맷·린트 stylistic 충돌무한 루프포맷 단일화, 린트 stylistic 제거
Prettier 4 Rust 백엔드를 즉시 의존베타 단계의 변동성안정화 확인 후 도입

다음 글 예고

다음 글은 "빌드 도구 2026 — Vite, Turbopack, Rspack, Rolldown, esbuild, swc, oxc의 진짜 위치"다. 이번 글이 "코드를 어떻게 정돈하는가"의 글이라면, 다음 글은 "코드를 어떻게 묶는가"의 글이다. esbuild의 Go, swc/Turbopack의 Rust, Vite의 esbuild+Rolldown 전환, Rspack의 Rust 재작성, oxc의 컴포넌트화 — 같은 Rust 재작성 패턴이 빌드 도구에서 어떻게 반복되는지, 그리고 무엇을 골라야 하는지를 정리한다.


참고 / References

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다