Biome: 포맷팅과 린팅을 하나로 통합하기

Biome: 포맷팅과 린팅을 하나로 통합하기

자바스크립트 프로젝트를 세팅하다 보면 ESLint 설정하고, Prettier 설정하고, 둘이 충돌하지 않게 연동하고… 이런 과정이 꽤 번거롭죠? 거기에 Stylelint까지 더하면 설정 파일만 서너 개가 됩니다. 🤯

이런 불편함을 해결하려는 도구가 바로 Biome입니다. 포맷터와 린터를 하나의 도구로 합쳐서, 설정도 간단하고 속도도 빠른 올인원 웹 개발 도구를 표방하고 있는데요.

이번 글에서는 Biome이 어떤 도구인지, 어떻게 설치하고 사용하는지, 기존의 ESLint/Prettier와 비교하면 어떤 차이가 있는지 살펴보겠습니다.

Biome이란?

Biome은 웹 프로젝트를 위한 통합 도구 체인(toolchain)입니다. Rust로 작성되어 속도가 매우 빠르고, 포맷팅과 린팅을 하나의 도구로 한꺼번에 돌립니다.

원래 Rome이라는 이름으로 시작했다가, 프로젝트 방향이 바뀌면서 커뮤니티가 포크(fork)해서 Biome이라는 이름으로 이어오고 있고요. 현재 JavaScript, TypeScript, JSX, TSX, JSON, CSS, GraphQL, HTML을 지원합니다.

어떤 점이 좋은지 정리하면 이렇습니다:

  • 빠른 속도: Rust 기반이라 대규모 코드베이스에서도 포맷팅이 순식간에 끝남
  • 설정 최소화: 별도 설정 없이도 바로 사용 가능
  • 포맷터 + 린터 통합: ESLint와 Prettier를 따로 설치할 필요 없음
  • 풍부한 린트 규칙: ESLint, typescript-eslint, eslint-plugin-react 등에서 가져온 434개 이상의 규칙 내장

설치

Biome은 npm 패키지로 제공됩니다. 프로젝트에 개발 의존성으로 설치하면 되는데, -E 플래그로 정확한 버전을 고정하는 걸 공식 문서에서 권장하고 있습니다.

npm i -D -E @biomejs/biome

pnpm이나 bun을 쓴다면:

pnpm add -D -E @biomejs/biome
bun add -D -E @biomejs/biome

설치 후 설정 파일을 생성합니다:

npx @biomejs/biome init

이러면 프로젝트 루트에 biome.json 파일이 만들어집니다.

biome.json
{
  "$schema": "https://biomejs.dev/schema.json",
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  }
}

이것만으로도 포맷터와 린터가 바로 동작합니다.

코드 포맷팅

Biome의 포맷터는 Prettier와 97% 호환되는 결과를 내놓는다고 합니다. 사용법도 간단합니다.

현재 코드가 올바르게 포맷팅되어 있는지 확인만 하려면:

npx biome format ./src

실제로 파일을 수정하려면 --write 플래그를 붙입니다:

npx biome format --write ./src

포맷팅 옵션은 biome.json에서 설정합니다:

biome.json
{
  "formatter": {
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single",
      "semicolons": "asNeeded"
    }
  }
}

기본값은 들여쓰기가 탭(tab)이고 줄 너비가 80자입니다. Prettier에서 넘어온다면 위처럼 기존 설정에 맞춰 조정하면 되고요.

특정 코드 구간의 포맷팅을 건너뛰고 싶으면 주석을 달아줍니다:

// biome-ignore format: 여기는 의도적으로 정렬함
const matrix = [
  [1, 0, 0],
  [0, 1, 0],
  [0, 0, 1],
];

코드 린팅

Biome의 린터는 434개 이상의 규칙을 내장하고 있습니다. ESLint 코어 규칙, typescript-eslint, eslint-plugin-react, eslint-plugin-jsx-a11y 등 여러 플러그인에서 가져온 규칙이 포함되어 있어서, 별도로 플러그인을 설치하지 않아도 됩니다.

린트 검사를 실행하려면:

npx biome lint ./src

자동으로 고칠 수 있는 문제를 수정하려면:

npx biome lint --write ./src

여기서 Biome이 재미있는 점은 수정의 안전도를 구분한다는 겁니다. 안전한 수정(safe fix)은 코드의 의미를 바꾸지 않는 수정이고, 안전하지 않은 수정(unsafe fix)은 동작이 달라질 수도 있는 수정입니다. --write는 안전한 수정만 적용하고, 안전하지 않은 수정까지 포함하려면 --unsafe 플래그를 함께 씁니다.

린트 규칙은 8개 그룹으로 나뉩니다:

그룹설명
correctness버그를 일으키기 쉬운 코드 감지
suspicious의심스러운 패턴 경고
style코딩 스타일 일관성
complexity불필요하게 복잡한 코드 감지
performance성능에 영향을 줄 수 있는 코드 감지
a11y접근성 문제 검사
security보안 취약점 감지
nursery아직 실험 단계인 규칙

개별 규칙을 세부 조정하고 싶다면 biome.json에서 설정합니다:

biome.json
{
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "style": {
        "noVar": "error",
        "useConst": "error"
      },
      "suspicious": {
        "noExplicitAny": "warn"
      }
    }
  }
}

특정 줄에서 린트를 무시하고 싶으면:

// biome-ignore lint/suspicious/noExplicitAny: 레거시 코드 호환
const data: any = fetchData();

check 명령어

포맷팅과 린팅을 따로 돌리기 귀찮다면 check 명령어 하나면 됩니다. 포맷팅 검사, 린트 검사, import 정렬을 한 방에 처리하거든요.

npx biome check ./src

자동 수정까지 하려면 --write를 붙이면 되고요:

npx biome check --write ./src

package.json에 스크립트로 등록해두면 편합니다:

package.json
{
  "scripts": {
    "check": "biome check ./src",
    "check:fix": "biome check --write ./src"
  }
}

에디터 통합

VS Code를 쓴다면 Biome 확장 프로그램을 설치하면 됩니다. 마켓플레이스에서 “Biome”을 검색해서 설치하고, 다음과 같이 설정하면 저장할 때마다 자동으로 포맷팅과 린트 수정이 적용됩니다:

.vscode/settings.json
{
  "editor.defaultFormatter": "biomejs.biome",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "quickfix.biome": "explicit",
    "source.organizeImports.biome": "explicit"
  }
}

IntelliJ IDEA 사용자라면 공식 Biome 플러그인이 있고, Neovim에서는 LSP 설정으로 연동합니다.

코드를 작성하는 도중에도 에러나 경고를 바로 보여주기 때문에, 커맨드 라인에서 따로 돌릴 필요 없이 문제를 즉시 파악할 수 있죠.

Git Hook 연동

커밋하기 전에 자동으로 코드를 검사하고 싶다면 Git Hook과 연동하면 됩니다. Biome 공식 문서에서는 여러 가지 방법을 소개하고 있는데, 가장 흔한 조합인 husky + lint-staged를 기준으로 설명하겠습니다.

먼저 husky와 lint-staged를 설치합니다:

npm i -D husky lint-staged
npx husky init

.husky/pre-commit 파일을 수정합니다:

.husky/pre-commit
npx lint-staged

package.json에 lint-staged 설정을 추가합니다:

package.json
{
  "lint-staged": {
    "*": ["biome check --write --no-errors-on-unmatched"]
  }
}

--no-errors-on-unmatched 플래그는 Biome이 처리하지 않는 파일 형식(예: 이미지)이 스테이징에 포함되어 있어도 에러를 내지 않게 해줍니다.

이렇게 설정하면 git commit 할 때마다 자동으로 변경된 파일에 대해서 포맷팅과 린팅이 적용됩니다.

ESLint/Prettier에서 마이그레이션

이미 ESLint와 Prettier를 쓰고 있는 프로젝트라면 Biome의 마이그레이션 도구가 도움이 됩니다.

npx @biomejs/biome migrate eslint --write

이 명령어를 실행하면 .eslintrc 파일을 읽어서 대응되는 Biome 규칙을 biome.json에 자동으로 설정해줍니다. 물론 모든 ESLint 플러그인과 규칙이 1:1로 대응되는 건 아니라서, 마이그레이션 후에 결과를 꼭 검토해야 합니다.

Prettier 설정도 비슷한 방식으로 옮깁니다:

npx @biomejs/biome migrate prettier --write

마이그레이션이 완료되면 기존 ESLint/Prettier 패키지를 제거하고 관련 설정 파일을 정리합니다:

npm uninstall eslint prettier eslint-config-prettier
rm .eslintrc.json .prettierrc

Biome vs ESLint + Prettier

기존의 ESLint + Prettier 조합과 비교했을 때 어떤 차이가 있는지 정리해보겠습니다.

항목ESLint + PrettierBiome
설치패키지 2개 + 플러그인 여러 개패키지 1개
설정 파일.eslintrc, .prettierrcbiome.json 하나
속도Node.js 기반Rust 기반 (약 35배 빠름)
포맷팅 호환Prettier (원본)Prettier 97% 호환
린트 규칙 수플러그인에 따라 다름434개 이상 내장
CSS 린팅별도로 Stylelint 필요내장 지원
생태계방대한 플러그인 생태계아직 성장 중
커스텀 규칙직접 작성 가능아직 미지원

Biome의 가장 큰 장점은 단순함속도입니다. 패키지 하나만 설치하면 포맷팅부터 린팅까지 바로 되고, Rust 엔진 덕분에 대규모 프로젝트에서도 체감될 만큼 빠릅니다.

반면 ESLint의 강점은 유연성입니다. 수천 개의 플러그인과 커뮤니티 규칙이 있고, 필요하다면 직접 커스텀 규칙을 만들 수도 있습니다. 이런 확장성이 중요한 프로젝트라면 당분간 ESLint를 유지하는 게 나을 수 있습니다.

마치며

Biome은 “웹 개발 도구가 너무 많고 복잡하다”는 문제를 정면으로 해결하려는 도구입니다. ESLint와 Prettier를 따로따로 설치하고 설정 충돌을 해결하느라 시간을 보내는 대신, biome.json 파일 하나로 포맷팅과 린팅을 한 번에 관리할 수 있다는 건 확실한 매력이죠.

물론 아직은 ESLint의 플러그인 생태계를 완전히 대체하기에는 이른 감이 있습니다. 하지만 새로운 프로젝트를 시작하거나 기존 설정이 복잡하게 얽혀있어서 갈아엎고 싶은 상황이라면 Biome을 한 번 시도해볼 만합니다.

관심이 있으시다면 공식 사이트에서 더 자세한 내용을 확인해보세요.

관련 포스팅

This work is licensed under CC BY 4.0 CC BY

개발자를 위한 뉴스레터

달레가 정리한 AI 개발 트렌드와 직접 만든 콘텐츠를 전해드립니다.

Discord