설정 파일 다섯 개를 biome.json 하나로 — Biome 2.x로 ESLint·Prettier를 걷어낼 때 얻는 것과 남겨둘 것
새 TypeScript 프로젝트를 셋업할 때마다 같은 루틴을 반복해 왔습니다. .eslintrc.js를 만들고, eslint-config-prettier로 두 도구가 충돌하지 않게 연결하고, @typescript-eslint/* 의존성을 추가하고, eslint-plugin-import로 임포트 순서를 잡고, .prettierrc도 별도로 작성합니다. 여기까지 오면 설정 파일만 다섯 개, 관련 패키지는 열 개 가까이 됩니다. 저는 이게 "당연한 개발 환경"인 줄 알았습니다.
Biome 2.x는 이 복잡도를 biome.json 파일 하나로 압축합니다. Rust로 작성된 단일 바이너리가 린트·포맷·임포트 정렬을 한 번의 패스로 처리하고, 자체 타입 추론 엔진을 통해 일부 타입-인식 린트 규칙까지 지원합니다(단, TypeScript 컴파일러 수준의 완전한 추론은 아닙니다 — 뒤에서 자세히 다룹니다). Biome v2 공식 릴리스에서 타입-인식 린팅과 GritQL 기반 플러그인, 도메인 시스템이 도입됐고, 2026년 기준 v2.5 릴리스에서는 누적 500개 이상의 규칙과 크로스-파일 린팅이 지원됩니다.
이 글에서는 마이그레이션의 구체적인 과정과 함께 무엇을 얻고, 어디서 멈춰야 하는지를 실제 설정 예시로 살펴봅니다.
ESLint + Prettier 조합이 쌓아온 복잡도
도구가 문제가 아니라 조합이 문제였다
ESLint와 Prettier를 함께 쓰는 전형적인 프로젝트의 관련 파일 목록입니다.
.eslintrc.js(또는eslint.config.js).eslintignore.prettierrc(또는prettier.config.js).prettierignoretsconfig.json— 타입-인식 규칙을 위한parserOptions.project설정
여기에 @typescript-eslint/parser, @typescript-eslint/eslint-plugin, eslint-config-prettier, eslint-plugin-import 같은 패키지들이 쌓입니다. 각 패키지 사이의 버전 호환성을 관리하는 것도 은근히 까다롭고, 저도 @typescript-eslint를 올렸다가 다른 플러그인이 깨지는 경험을 여러 번 했습니다.
Biome v2에서 달라진 세 가지
v1 시절 Biome는 규칙 수가 적어 ESLint를 대체하기엔 역부족이었습니다. v2 릴리스에서 결정적인 세 가지가 추가됐습니다.
타입-인식 린팅(부분 지원): 기존에 @typescript-eslint로 타입 기반 규칙(no-floating-promises, await-thenable 등)을 쓰려면 tsconfig.json을 파서에 물려주고 tsc가 타입 정보를 읽어야 했습니다. Biome v2는 자체 타입 추론 엔진을 도입해 일부 타입-인식 규칙을 tsc 없이 적용합니다. 다만 이 추론기는 TypeScript 컴파일러와 동등한 수준이 아니라 Biome가 처리 가능한 범위에 한정되므로, 여전히 완전한 타입 검사에는 tsc가 필요합니다.
GritQL 플러그인(2026년 기준 실험적 단계): v2부터 GritQL로 커스텀 린트 규칙을 작성할 수 있습니다. Biome Linter Plugins 공식 문서에 명시된 대로 아직 실험적 기능이므로, 프로덕션 도입 전 스펙 변경 가능성을 감안해야 합니다.
도메인 시스템: package.json 의존성을 분석해 React를 쓰는 프로젝트에는 React 관련 규칙을, Next.js면 Next.js 전용 규칙을 자동으로 활성화합니다. 설정에서 플러그인을 일일이 등록하지 않아도 됩니다.
Biome 프로젝트는 다양한 기업의 후원을 받고 있는데, 후원 등급이나 형태(금전적 스폰서, 인프라 후원, 사용 사례 공개 등)는 회사마다 다릅니다. 정확한 후원 구조는 Biome 공식 사이트의 스폰서 페이지에서 직접 확인하는 걸 권합니다.
마이그레이션 — 실제로 어떻게 진행되나
Biome는 migrate 서브커맨드로 기존 설정을 자동 변환해 줍니다. Prettier 먼저, ESLint 나중에 처리하면 충돌이 줄어듭니다.
# 1. 정확한 버전으로 설치 (--save-exact 권장)
npm install --save-dev --save-exact @biomejs/biome
# 2. biome.json 초기화
npx @biomejs/biome init
# 3. Prettier 설정 → biome.json으로 변환
npx @biomejs/biome migrate prettier --write
# 4. ESLint 설정 → biome.json으로 변환
npx @biomejs/biome migrate eslint --write
# 5. 변환 결과 검증
npx @biomejs/biome check .놓치기 쉬운 포인트 세 가지
첫 번째, Prettier 기본값 차이입니다. Biome는 기본적으로 탭 들여쓰기를 사용합니다. 기존 프로젝트가 스페이스를 쓰고 있었다면 migrate prettier가 변환해 주지만, 새로 설정할 때는 명시적으로 지정해줄 필요가 있습니다.
두 번째, 권장 규칙 세트의 차이입니다. migrate eslint는 기존 ESLint 설정 파일에 명시된 규칙을 Biome 대응 규칙으로 옮겨줍니다. 그런데 ESLint의 eslint:recommended 세트와 Biome의 recommended 세트는 애초에 규칙 구성이 다른 별개의 세트입니다. 따라서 마이그레이션 후에 Biome의 권장 세트를 쓰고 싶다면 biome.json에서 linter.rules.recommended를 명시적으로 활성화해야 합니다. 저도 처음에 이걸 모르고 "규칙이 왜 이렇게 적지?" 했던 기억이 납니다.
세 번째, migrate prettier는 JSON5, TOML, YAML 형식의 Prettier 설정 파일을 읽지 못합니다. .prettierrc가 JSON이 아닌 형식이라면 수동으로 옮겨줘야 합니다.
마이그레이션 후 제거 가능한 패키지들
npm uninstall eslint prettier \
eslint-config-prettier \
eslint-config-next \
eslint-plugin-react \
eslint-plugin-import \
@typescript-eslint/parser \
@typescript-eslint/eslint-plugin.eslintrc.js, .eslintignore, .prettierrc, .prettierignore 파일도 함께 제거할 수 있습니다.
biome.json 설정 심화
린트 + 포맷 + 임포트 정렬 일괄 설정
아래는 2026년 기준 v2.5 계열에서 사용하는 개념적 예시입니다. $schema URL은 실제로 설치한 버전에 맞춰 조정하고, 각 옵션의 유효 값은 Biome 설정 레퍼런스에서 확인해 주세요.
{
"$schema": "https://biomejs.dev/schemas/2.5.0/schema.json",
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"assist": {
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}임포트 정렬 경로는 organizeImports 공식 문서에 있는 대로 v2부터 assist.actions.source.organizeImports로 이동했습니다(v1에서는 최상위 organizeImports 섹션이었습니다). 기존에 eslint-plugin-import로 처리하던 임포트 순서 정렬과 import 병합·분리 주석 처리가 여기서 담당됩니다.
도메인 시스템(react, next 등)을 함께 쓰고 싶다면 스키마에서 정확한 키·값 형식을 확인한 뒤 활성화하는 걸 권합니다. 도메인별 지원 여부와 값 형식이 마이너 버전에 따라 조정될 수 있어, 여기서는 안전하게 recommended만 켠 최소 예시를 보여드렸습니다.
모노레포 설정 상속
Biome는 여러 biome.json을 워크스페이스 안에 두고 서로 상속·확장하는 방식을 지원합니다. 정확한 필드명(extends, root)과 각 필드에 넣을 값의 형식은 Biome 대규모 프로젝트 적용 가이드에 정리되어 있으니, 모노레포에 도입할 때는 해당 문서의 예시를 그대로 참고하는 편이 가장 안전합니다. 문서에 따라 상대 경로 또는 워크스페이스 지시자를 사용하며, 마이너 버전에 따라 세부 문법이 조정되므로 카피 앤 페이스트할 때는 설치된 버전의 문서를 확인해 주세요.
CI 통합 — 단일 패스로 처리
기존에 ESLint와 Prettier를 각각 실행하던 CI 스텝을 다음으로 교체할 수 있습니다.
- name: Biome check
run: npx @biomejs/biome ci .biome ci는 biome check와 달리 파일을 수정하지 않고 검사만 합니다. 포맷·린트·임포트 정렬을 단일 패스로 처리하기 때문에 CI 실행 시간이 줄어드는 효과가 있습니다.
실제 속도 차이는 프로젝트 규모, 러너 스펙, 파일 수, 사용 중인 규칙 세트에 따라 크게 달라집니다. 공개된 벤치마크 수치는 여러 곳에 있지만 측정 조건이 서로 다르므로, 도입 여부를 결정할 때는 본인 프로젝트에서 time 명령으로 직접 비교해 보는 게 가장 확실합니다.
어디까지 교체할 수 있고, 어디서 멈춰야 하는가
장점
| 항목 | 내용 |
|---|---|
| 속도 | Rust 기반 멀티 코어 병렬 처리, Node.js 기동 비용 없음 (실측치는 프로젝트별로 다름) |
| 설정 단순화 | 설정 파일 5개 이상 → biome.json 1개 |
| 타입-인식 린팅(부분) | tsc 없이 일부 타입 기반 규칙 적용 |
| 단일 툴체인 | 린트·포맷·임포트 정렬을 한 번의 패스로 처리 |
주의사항
| 항목 | 내용 |
|---|---|
| 타입 추론 범위 | Biome 자체 추론기는 TypeScript 컴파일러와 동등하지 않음. 완전한 타입 검사는 여전히 tsc 필요 |
| Prettier 호환성 | 출력이 거의 호환되지만 100%는 아님. 기본값 차이(탭 vs 스페이스)와 소수 엣지 케이스에서 diff 발생 가능 |
| 플러그인 생태계 | ESLint 대비 제한적. import/no-cycle, eslint-plugin-security, eslint-plugin-jest 등 미지원 또는 실험 단계 |
| Vue·Svelte·Astro | 2026년 기준 지원 수준은 공식 문서에서 최신 상태 확인 필요 |
| JSON5·YAML Prettier 설정 | migrate prettier 자동 변환 불가, 수동 작업 필요 |
| GritQL 플러그인 | 실험적 기능. 프로덕션 도입 전 스펙 안정성 검토 필요 |
ESLint를 완전히 버릴 수 없을 때
모든 ESLint 플러그인을 당장 버릴 수 없다면 두 도구를 병행 운영할 수 있습니다. 이때 필요한 건 Biome와 겹치는 ESLint 규칙(포맷 관련 규칙 등)을 꺼두는 설정입니다. 아래는 개념적 예시이며, 실제 사용 시에는 병행에 사용할 config 패키지의 최신 문서에서 export 형태와 이름을 확인해 주세요.
// eslint.config.js — 개념적 예시
export default [
// Biome와 충돌하는 규칙을 비활성화하는 config를 여기에 추가
// Biome가 아직 지원하지 않는 특수 플러그인만 남긴다
];포맷과 기본 린트는 Biome에 맡기고, 아직 Biome가 지원하지 않는 특수 규칙만 ESLint에 남겨두는 방식으로 단계적 전환이 가능합니다.
판단 기준으로 정리하며
React + TypeScript 기반 프로젝트에서 완전히 전환해 쓰고 있고, 지금까지 큰 불편함은 없습니다. 설정 파일이 줄어드는 것만으로도 유지보수 부담이 체감상 확실히 줄었고, CI에서 린트·포맷 단계가 빠르게 끝나는 것도 좋습니다.
결국 완전 전환과 병행 운영을 가르는 판단 기준은 두 가지로 압축됩니다.
- 의존하는 ESLint 플러그인이 Biome에 대응 규칙이 있는가.
import/no-cycle,eslint-plugin-security, 프로젝트 자체 커스텀 규칙 등 대체 불가능한 규칙에 의존한다면 병행 운영이 현실적입니다. - 사용 중인 프레임워크가 Biome의 파서 지원 대상인가. JavaScript·TypeScript·JSX·TSX 위주라면 전환에 무리가 없지만, Vue·Svelte·Astro가 코드의 상당 부분을 차지한다면 도입 시점의 지원 수준을 공식 문서에서 확인한 뒤 결정해야 합니다.
이 두 기준에서 모두 초록불이 켜지면 완전 전환, 하나라도 걸리면 eslint-config-biome 계열로 병행 운영부터 시작하는 게 안전한 접근입니다.