tj.park
← Back

ESLint + Prettier 걷어내고 Biome 한 줄로 끝내기

·1 min read· views
#biome#tooling#eslint#prettier

이 블로그를 만들 때 처음부터 Biome을 골랐습니다. 그 결정의 근거가 무엇이었는지, 그리고 ESLint+Prettier 조합을 쓰던 머릿속을 어떻게 비웠는지 정리해 둡니다.

한 줄 요약

항목이전 (ESLint + Prettier)이후 (Biome)
devDependency6~10개1개
설정 파일.eslintrc, .prettierrc, .eslintignore, .prettierignorebiome.json 하나
린트 + 포맷두 명령biome check 한 번
실행 속도초 단위거의 즉시

왜 Biome인가

ESLint와 Prettier는 좋은 도구지만, 같이 쓰면 항상 같은 풍경이 펼쳐집니다.

  • eslint, prettier, eslint-config-prettier, eslint-plugin-*, 파서까지 설치 → 버전 매트릭스가 늘어남
  • 포매터와 린터가 충돌하지 않도록 eslint-config-prettier로 룰을 꺼야 함
  • 두 도구가 각자 캐시·각자 ignore 파일·각자 설정 스키마를 가짐
  • 큰 저장소에서 lint가 무거워짐

Biome은 이 모든 걸 Rust로 만든 단일 바이너리 하나에 합쳤습니다. 포매터와 린터가 같은 파서를 공유하니 충돌이 없고, 설정도 한 파일이면 끝납니다.

설치

pnpm add -D -E @biomejs/biome

-E로 정확한 버전을 박아두는 게 권장입니다. 포맷 결과가 버전 사이에서 살짝 달라질 수 있어서, 팀원과 CI가 항상 같은 결과를 내도록 고정합니다.

설정

이 블로그가 쓰는 biome.json 전체입니다.

{
  "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
  "vcs": { "enabled": false, "clientKind": "git", "useIgnoreFile": true },
  "organizeImports": { "enabled": true },
  "linter": {
    "enabled": true,
    "rules": { "recommended": true }
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100
  },
  "javascript": {
    "formatter": { "quoteStyle": "double", "semicolons": "asNeeded" }
  },
  "files": {
    "ignore": [".velite", ".next", "node_modules", "public"]
  }
}

읽어볼 만한 부분만 짚으면,

  • vcs.useIgnoreFile: .gitignore를 그대로 ignore 파일로 재활용합니다. 별도의 .biomeignore를 만들지 않아도 됩니다.
  • organizeImports: import 정렬을 켭니다. eslint-plugin-import의 자리를 대신합니다.
  • semicolons: "asNeeded": 세미콜론을 필요할 때만 붙입니다. Prettier의 semi: false와 같은 결.
  • files.ignore: 생성물(.velite, .next)과 정적 파일을 빼둡니다.

스크립트

package.json은 두 줄이면 끝납니다.

{
  "scripts": {
    "lint": "biome check .",
    "format": "biome format --write ."
  }
}
  • biome check린트 + 포맷 검사 + import 정렬 검사를 한 번에 합니다. CI에서는 이 한 줄만 돌리면 됩니다.
  • 자동 수정까지 같이 하고 싶다면 biome check --write .을 쓰면 됩니다.

에디터 연동

VS Code는 공식 확장을 깔고 워크스페이스 설정에 한 줄.

{
  "editor.defaultFormatter": "biomejs.biome",
  "editor.formatOnSave": true,
  "[typescript]": { "editor.defaultFormatter": "biomejs.biome" },
  "[typescriptreact]": { "editor.defaultFormatter": "biomejs.biome" }
}

Prettier 확장과 ESLint 확장은 비활성화해도 됩니다. 사실 안 꺼두면 두 포매터가 싸워서 저장할 때마다 결과가 달라지는 사고가 납니다.

무엇이 사라졌나

마이그레이션이라는 단어가 거창하게 들리지만, 이 블로그 규모에서는 사실상 파일 정리에 가깝습니다.

  • 지운 devDependency: eslint, eslint-config-*, eslint-plugin-*, prettier, eslint-config-prettier, 관련 파서들
  • 지운 설정 파일: .eslintrc.*, .prettierrc.*, .eslintignore, .prettierignore
  • 늘어난 파일: biome.json 하나

package.json의 devDependencies가 한 화면 안에 다 들어오게 된 게 가장 큰 체감 변화였습니다.

기존 설정을 옮겨야 한다면

이미 ESLint·Prettier 설정이 쌓여 있는 프로젝트라면 자동 변환을 써보세요.

pnpm biome migrate eslint --write
pnpm biome migrate prettier --write

각각 기존 설정을 읽어서 biome.json에 동등한 항목을 채워줍니다. 100% 1:1로 옮겨지지는 않지만, 손으로 옮기는 작업의 80%는 줄여줍니다.

마치며

도구가 단순해질수록 신경 쓸 게 줄어듭니다. biome check 한 번이면 끝나는 환경에서 글을 쓰는 건, 그 자체로 작은 즐거움이 있습니다.

accent