Biome 완벽 가이드 — ESLint + Prettier 대체 Rust 기반 JS/TS 툴체인
이 글의 핵심
Biome은 ESLint + Prettier의 역할을 한 개의 Rust 바이너리가 수행하도록 재구현한 JavaScript/TypeScript 툴체인입니다. Rome 프로젝트의 포크로 2023년 출범, 2024년 v1 GA, 2026년 현재 v2까지 발전해 Formatter·Linter·Import Sorter를 통합 제공합니다. ESLint 대비 10-100배 빠르고 제로 설정으로 바로 쓸 수 있어 신규 프로젝트·모노레포에서 빠르게 채택되고 있습니다.
왜 Biome인가
JS/TS 프로젝트의 표준 도구 체인은 보통 이랬습니다.
package.json:
eslint, @typescript-eslint/*, eslint-config-*, eslint-plugin-*,
prettier, prettier-plugin-*, eslint-config-prettier, eslint-plugin-prettier,
lint-staged, husky, ...
- 설정 파일 3-5개 (
.eslintrc.js,.prettierrc,tsconfig.json등) - 실행 속도 느림 (수백ms ~ 수십 초)
- 두 도구 경계(포맷 vs 린트)에서 자주 충돌
- 플러그인 업데이트 지옥
Biome은 이를 단일 Rust 바이너리 + biome.json 하나로 해결합니다.
설치
pnpm/npm/yarn
pnpm add -D --save-exact @biomejs/biome
pnpm biome init
biome init이 biome.json을 생성합니다. --save-exact는 포맷팅 결과 안정성을 위해 버전 고정 권장.
글로벌 CLI (선택)
# Rust 바이너리 직접
brew install biome
# 또는 cargo-binstall biome-cli
기본 설정 (biome.json)
{
"$schema": "https://biomejs.dev/schemas/2.1.0/schema.json",
"files": {
"ignoreUnknown": true,
"includes": ["src/**", "tests/**", "scripts/**"]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"lineEnding": "lf"
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"jsxQuoteStyle": "double",
"trailingCommas": "all",
"semicolons": "asNeeded",
"arrowParentheses": "always"
}
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"style": {
"useConst": "error",
"noParameterAssign": "error"
},
"suspicious": {
"noExplicitAny": "warn"
},
"correctness": {
"noUnusedVariables": "error"
}
}
},
"assist": {
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}
실행
# 포맷 + 린트 (수정 안함)
pnpm biome check
# 자동 수정 포함
pnpm biome check --write
# 포맷만
pnpm biome format --write src/
# 린트만
pnpm biome lint src/
# 특정 파일
pnpm biome check src/app.ts
# CI 모드 (실패 시 exit 1)
pnpm biome ci
package.json 스크립트 예시
{
"scripts": {
"check": "biome check",
"check:fix": "biome check --write",
"format": "biome format --write .",
"lint": "biome lint .",
"ci": "biome ci ."
}
}
VS Code 통합
- 확장 설치:
biomejs.biome - 설정:
// .vscode/settings.json
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports.biome": "explicit",
"quickfix.biome": "explicit"
},
"[typescript]": { "editor.defaultFormatter": "biomejs.biome" },
"[typescriptreact]": { "editor.defaultFormatter": "biomejs.biome" },
"[javascript]": { "editor.defaultFormatter": "biomejs.biome" },
"[javascriptreact]": { "editor.defaultFormatter": "biomejs.biome" },
"[json]": { "editor.defaultFormatter": "biomejs.biome" }
}
ESLint/Prettier에서 마이그레이션
1) Prettier 설정 가져오기
pnpm biome migrate prettier --write
.prettierrc를 읽어 biome.json의 formatter 섹션을 자동 생성합니다.
2) ESLint 설정 가져오기
pnpm biome migrate eslint --write
규칙을 최대한 대응되는 Biome 규칙으로 매핑하고, 대응 안 되는 항목은 주석으로 안내합니다.
3) 의존성 제거
pnpm remove eslint prettier \
@typescript-eslint/eslint-plugin @typescript-eslint/parser \
eslint-config-prettier eslint-plugin-prettier \
eslint-config-airbnb ... # 프로젝트에 맞게
4) 설정 파일 삭제
rm .eslintrc* .prettierrc* .eslintignore .prettierignore
5) CI/precommit 훅 교체
# package.json
"lint-staged": {
"*.{js,jsx,ts,tsx,json}": "biome check --write --no-errors-on-unmatched"
}
모노레포 적용
루트에 biome.json을 두고 각 패키지가 필요 시 확장하는 구조가 가장 단순합니다.
// apps/web/biome.json
{
"$schema": "https://biomejs.dev/schemas/2.1.0/schema.json",
"extends": ["../../biome.json"],
"javascript": {
"globals": ["window", "document"]
},
"linter": {
"rules": {
"suspicious": {
"noConsole": "error"
}
}
}
}
# 모노레포 루트에서
pnpm biome check --changed --since=origin/main
--changed로 변경된 파일만 처리해 CI 시간을 더욱 단축할 수 있습니다.
GitHub Actions
name: ci
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: pnpm/action-setup@v4
with: { version: 9 }
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm biome ci --reporter=github
--reporter=github는 PR 리뷰 코멘트 포맷으로 출력해 GitHub Actions annotations에 직접 연결됩니다.
주요 규칙 카테고리
- a11y: 접근성 (
useAltText,useKeyWithClickEvents등) - complexity: 복잡도 (
noBannedTypes,noExtraBooleanCast) - correctness: 버그 가능성 (
noUnusedVariables,noUndeclaredVariables) - performance: 성능 (
noDelete,noAccumulatingSpread) - security: 보안 (
noDangerouslySetInnerHtml) - style: 스타일 (
useConst,useTemplate) - suspicious: 의심스러운 코드 (
noExplicitAny,noConsole) - nursery: 실험적 규칙
특정 규칙 비활성화
// biome-ignore lint/suspicious/noExplicitAny: legacy API
const data: any = fetchLegacy()
// biome-ignore lint: 전체 카테고리
const x = undefined
Next.js + TypeScript 풀스택 예시
{
"$schema": "https://biomejs.dev/schemas/2.1.0/schema.json",
"files": {
"includes": ["app/**", "components/**", "lib/**", "src/**"],
"experimentalScannerIgnores": [".next/", "node_modules/", "dist/"]
},
"linter": {
"rules": {
"recommended": true,
"style": {
"useImportType": "error",
"useExportType": "error"
},
"nursery": {
"useSortedClasses": {
"level": "warn",
"options": {
"attributes": ["className"],
"functions": ["clsx", "cva", "cn", "tw"]
}
}
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"trailingCommas": "all",
"semicolons": "asNeeded"
}
}
}
Tailwind class 정렬까지 Biome이 처리하면 prettier-plugin-tailwindcss도 제거 가능.
Astro / Vue / Svelte 대응
Biome은 기본적으로 TS/JS 중심이고 SFC(Single File Component) 지원은 .vue·.svelte·.astro 중 일부만 실험적. 이들 프로젝트에서는:
- Astro:
.astro파일은 Prettier + Astro 플러그인 유지,.ts/.tsx는 Biome - Vue:
<script>블록만 Biome이 처리 가능하지만 현재까지 불완전 → 기존 ESLint 유지 - Svelte:
.svelte내부는 아직 제한적 →svelte-check+prettier-plugin-svelte병행
SFC 지원은 빠르게 개선되고 있으니 로드맵 확인 권장.
성능 비교 예시
| 도구 | 대형 모노레포(15만 줄) | |
|---|---|---|
| ESLint + Prettier | 62초 | baseline |
| Biome | 2.8초 | 22배 빠름 |
CI에서의 효과:
- PR 린트 잡이 초 단위로 끝나 피드백 루프 단축
- 사전 커밋 훅이 거슬리지 않는 속도
- 개발자 로컬 머신 부담 감소
언제 ESLint를 유지해야 하나
- 특수 플러그인 필수 (
eslint-plugin-react-hooks심화 룰,eslint-plugin-next,eslint-plugin-vue등) - 팀이 자체 커스텀 ESLint 규칙 대량 보유
- 테스트 파일에 맞춤 규칙(
vitest,jest,testing-library) 필요 - 보안 전문 린터(
eslint-plugin-security) 활용
이 경우 혼용 구성(Biome = format + import sort + 기본 lint / ESLint = 특수 규칙)도 실무에서 많이 쓰입니다.
// .eslintrc.cjs
module.exports = {
extends: ["plugin:react-hooks/recommended", "plugin:next/core-web-vitals"],
rules: {
// Biome가 처리하는 것은 모두 off
"indent": "off",
"semi": "off",
"quotes": "off",
},
}
트러블슈팅
포맷이 Prettier와 살짝 다름
Biome 2의 호환성은 97%이지만 드문 예외가 있음. biome format --ide 로 diff 확인 후 팀 표준 확정.
TypeScript path alias가 안 잡힘
biome.json에 "javascript": { "jsxRuntime": "reactClassic" } 같은 설정이 아닌, TS 측 tsconfig.json의 paths를 자동 인식. 모노레포에서 루트 tsconfig가 아니라 각 패키지의 tsconfig를 읽는지 확인.
특정 파일이 검사 안 됨
files.includes·files.experimentalScannerIgnores·.gitignore 확인. Biome은 기본적으로 .gitignore를 따릅니다.
Editor에서 포맷이 적용되지 않음
- VS Code
Biome확장 설치 확인 editor.defaultFormatter가biomejs.biome인지[typescript]언어별 설정이 다른 포매터로 설정되어 있는지
모노레포에서 중복 실행
biome check packages/* 대신 루트에서 한 번에: biome check. Biome은 내부적으로 파일 그래프를 병렬 처리.
체크리스트
-
biome.json단일 설정 파일 - Prettier/ESLint 규칙 마이그레이션 완료
- VS Code/Cursor 기본 포매터 Biome
- 사전 커밋 훅 교체 (lint-staged)
- GitHub Actions
biome ci --reporter=github - import sort·Tailwind class sort 활성
- 팀 가이드: 특수 규칙은 ESLint 병행 여부 결정
- CI 시간·DX 개선 측정 후 공유
마무리
Biome은 “느린 ESLint·설정 지옥”에서 벗어나고 싶은 팀에게 가장 빠른 탈출구입니다. 2년 만에 Prettier 호환 97%·대부분의 공통 ESLint 규칙 커버까지 도달했고, 도입이 단순하고 효과는 즉각적입니다. 신규 프로젝트라면 처음부터 Biome으로 시작하고, 기존 프로젝트도 biome migrate로 하루 내 전환 가능합니다. CI 시간 단축·DX 향상·의존성 제거 세 마리 토끼를 잡을 수 있는 드문 기회이며 2026년 현재 Tauri·Astro·Bun·Vercel 등 주요 OSS 프로젝트가 공식 채택할 만큼 검증된 상태입니다.
관련 글
- ESLint 완벽 가이드
- Prettier 완벽 가이드
- TypeScript 완벽 가이드
- 모노레포 도구 완벽 가이드