ADR-0032: Frontend Linter & Formatter: Biome¶
Umbra 의 프론트엔드(
apps/web)는 lint 와 format 을 단일 도구 Biome 으로 통합한다. ESLint + Prettier 조합은 사용하지 않는다.
Status¶
Accepted
- Decided at — 2026-04-17
- Decided by — Pablo
Context¶
apps/web 스캐폴딩 직전 시점에 lint/format 도구 선택을 확정해야 한다. frontend-conventions.md 는 "Biome 또는 ESLint + Prettier" 로 결정을 보류해 두었고, 스캐폴딩에서 패키지/설정 파일을 만들기 전에 이 결정을 잠근다.
요구사항:
- TypeScript + React 19 + TanStack 생태계 지원
- Tailwind class 정렬 자동화
- IDE (VSCode, JetBrains) 통합
- CI 에서 빠른 실행 (PR feedback loop 단축)
- 설정 파일 수 최소화
Decision¶
apps/web 의 lint 와 format 을 Biome 단일 도구로 처리한다.
apps/web/biome.json— 단일 설정 파일 (lint + format + import sort)bun --cwd apps/web run lint→ 내부적으로biome checkbun --cwd apps/web run format→ 내부적으로biome format --write- Tailwind class 정렬은 Biome 의
nursery/useSortedClassesrule 사용 - ESLint, Prettier,
prettier-plugin-tailwindcss는 도입하지 않음
apps/web/package.json 의 devDependencies 는 @biomejs/biome 만 추가한다. 향후 Biome 가 미지원하는 React 전용 rule 이 필요해지면 ESLint 추가가 아니라 Biome plugin 또는 custom rule 로 해결한다.
Consequences¶
Positive¶
- 빠른 실행 — Biome 는 Rust 기반으로 ESLint+Prettier 조합 대비 ~10배 빠르다. CI 시간 단축
- 단일 설정 파일 —
eslint.config.js,.prettierrc,prettier.config.js,.eslintignore,.prettierignore다섯 파일이biome.json하나로 통합 - devDependencies 축소 — 평균 6~10개 패키지 (eslint, @typescript-eslint/*, prettier, prettier-plugin-tailwindcss, eslint-plugin-react-hooks 등) → 1개
- 포맷/린트 충돌 없음 — 단일 도구라 rule 간 모순 발생 불가
- IDE 응답성 개선 — Language Server 부팅이 빠름
Negative¶
- 생태계 성숙도 차이 — ESLint 의 plugin 생태계 (수천 개) 대비 Biome plugin 은 제한적. 특정 React 패턴 lint 가 누락될 수 있음
- Tailwind plugin 의 v4 대응 — Biome 의
useSortedClasses가 Tailwind v4 (CSS-first config) 의 모든 케이스를 다 다루지 못할 수 있음. 필요 시 IDE format-on-save 보조 - 레퍼런스 자료 차이 — React 커뮤니티 튜토리얼이 ESLint 가정인 경우가 많음
Neutral¶
- 설정 마이그레이션 비용은 0 (스캐폴딩 전 결정이므로)
- Biome v2 가 stable. v1 에서 v2 로의 호환성 이슈는 이미 정리됨
Alternatives considered¶
Alternative 1: ESLint + Prettier + plugins¶
Pros
- 업계 표준, 거의 모든 React 프로젝트의 기본 선택
- plugin 생태계가 매우 풍부 (
eslint-plugin-react-hooks,eslint-plugin-jsx-a11y,@typescript-eslint/*등) - 커스텀 rule 작성 자료 많음
Cons
- 설정 파일 분산 (eslint, prettier, ignore 파일들)
- devDependencies 많음 (보통 10개 이상)
- 두 도구가 format 영역에서 겹치므로
eslint-config-prettier같은 충돌 회피 패키지 필수 - 실행 속도 느림 (특히 monorepo 에서 누적)
Why rejected — Umbra 의 apps/web 규모(MVP 한 개 SPA)에서 ESLint 의 plugin 다양성 이점이 작고, 설정 단순성과 실행 속도의 이점이 더 크다. 후일 특정 rule 이 절실해지면 Biome 위에 ESLint 를 보조 도구로 추가하는 방식도 가능 (현 시점엔 불필요).
Alternative 2: Rome (Biome 의 전신)¶
Pros
- 동일한 단일 도구 컨셉
Cons
- 프로젝트 자체가 archive (Biome 가 fork 후 활발히 개발 중)
Why rejected — Rome 은 더 이상 유지보수되지 않음. Biome 가 사실상의 후속 프로젝트.
Alternative 3: dprint¶
Pros
- 빠른 format 도구
- plugin 시스템
Cons
- format 만 다루고 lint 는 별도 도구 필요 → 단일 도구 목적과 어긋남
Why rejected — Biome 가 lint + format 통합이라는 결정 기준에 더 부합.
Compliance¶
apps/web/biome.json은 commit 되며 root 컨벤션과 일치해야 함- CI 의
lint-webjob 은bunx biome ci .또는bun --cwd apps/web run lint사용 - PR 에서 lint 실패 시 merge 차단
- ESLint / Prettier 관련 패키지가
apps/web/package.json에 추가되면 review 단계에서 차단 - IDE 설정 권장 사항은
frontend-conventions.md에 명시
Revisit triggers¶
- Biome 가 1년 이상 stable release 없이 정체되면 ESLint+Prettier 로 회귀 검토
- 팀이 4명 이상으로 확장되며 React 전용 lint rule 다수 도입이 필요해지면 ESLint 보조 도입 검토
- Tailwind v4 의 class 정렬을 Biome 가 끝내 지원 못 하면
prettier-plugin-tailwindcss만 부분 도입