Biome — Toolchain Rust thay thế ESLint + Prettier, nhanh hơn 50 lần
Posted on: 4/26/2026 8:16:03 AM
Table of contents
- 1. Biome là gì?
- 2. Biome vs ESLint + Prettier — so sánh chi tiết
- 3. Cài đặt và cấu hình Biome
- 4. Kiến trúc bên trong Biome
- 5. Tính năng mới trong Biome v2.x (2026)
- 6. Migration từ ESLint + Prettier sang Biome
- 7. Tích hợp CI/CD và IDE
- 8. Biome với Vue.js projects
- 9. Benchmark thực tế trên monorepo
- 10. Tổng kết
- Nguồn tham khảo
Bạn đang dùng ESLint + Prettier và mỗi lần CI chạy lint mất 30-45 giây? Config file rải khắp nơi — .eslintrc.js, .prettierrc, .eslintignore, .prettierignore — và thỉnh thoảng chúng conflict nhau? Biome là câu trả lời: một toolchain duy nhất viết bằng Rust, vừa lint vừa format, nhanh hơn 25-50 lần so với combo ESLint + Prettier truyền thống.
1. Biome là gì?
Biome là một toolchain thống nhất cho web projects, viết hoàn toàn bằng Rust. Nó kết hợp formatter (thay Prettier) và linter (thay ESLint) vào một công cụ duy nhất, với một file cấu hình duy nhất biome.json. Biome hỗ trợ JavaScript, TypeScript, JSX, TSX, JSON, CSS, và GraphQL.
Tại sao Rust thay đổi cuộc chơi?
ESLint và Prettier viết bằng JavaScript — chạy trên V8 single-threaded. Biome viết bằng Rust với parser song song, xử lý multi-threaded, và zero-copy memory model. Kết quả: lint monorepo 10.000 dòng code trong ~200ms thay vì 3-5 giây.
2. Biome vs ESLint + Prettier — so sánh chi tiết
| Tiêu chí | Biome | ESLint + Prettier |
|---|---|---|
| Ngôn ngữ viết | Rust | JavaScript |
| Tốc độ lint (10k files) | ~0.8 giây | ~45 giây |
| Tốc độ format (10k files) | ~0.3 giây | ~12 giây |
| File cấu hình | 1 file (biome.json) | 4+ files (.eslintrc, .prettierrc, ignore files...) |
| Conflict format/lint | Không bao giờ (cùng 1 tool) | Thường xuyên (cần eslint-config-prettier) |
| Type-aware linting | Có (v2.0+) | Có (typescript-eslint) |
| Plugin system | GritQL plugins (v2.0+) | JavaScript plugins (hệ sinh thái lớn) |
| CSS linting | Có (built-in) | Cần stylelint riêng |
| LSP/IDE support | Built-in LSP server | Extensions riêng cho mỗi tool |
| Số lint rules | 491+ | ~300 core + plugins |
3. Cài đặt và cấu hình Biome
3.1. Cài đặt
# Cài vào dự án
npm install --save-dev --save-exact @biomejs/biome
# Hoặc dùng pnpm/bun
pnpm add -D @biomejs/biome
bun add -D @biomejs/biome
# Tạo cấu hình mặc định
npx @biomejs/biome init
3.2. File biome.json cơ bản
{
"$schema": "https://biomejs.dev/schemas/2.4.0/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"complexity": {
"noExcessiveCognitiveComplexity": {
"level": "warn",
"options": { "maxAllowedComplexity": 15 }
}
},
"suspicious": {
"noExplicitAny": "error"
},
"style": {
"useConst": "error",
"noNonNullAssertion": "warn"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"trailingCommas": "all",
"semicolons": "always"
}
},
"css": {
"linter": { "enabled": true },
"formatter": { "enabled": true }
}
}
3.3. Chạy Biome
# Format tất cả files
npx biome format --write .
# Lint và auto-fix
npx biome lint --write .
# Chạy cả hai (check = lint + format)
npx biome check --write .
# CI mode — chỉ kiểm tra, không sửa
npx biome ci .
4. Kiến trúc bên trong Biome
graph TD
A["Source Files
JS/TS/JSX/CSS/JSON"] --> B["Biome Core
Rust Engine"]
B --> C["Parser
Concrete Syntax Tree"]
C --> D{"Parallel Processing"}
D --> E["Formatter
Pretty-print CST"]
D --> F["Linter
491+ Rules Analysis"]
D --> G["Type Resolver
Type-aware rules"]
E --> H["Formatted Output"]
F --> I["Diagnostics
+ Auto-fix suggestions"]
G --> F
style B fill:#e94560,stroke:#fff,color:#fff
style C fill:#2c3e50,stroke:#fff,color:#fff
style D fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style E fill:#4CAF50,stroke:#fff,color:#fff
style F fill:#16213e,stroke:#fff,color:#fff
style G fill:#2c3e50,stroke:#fff,color:#fff
Pipeline xử lý của Biome — parse một lần, lint + format song song
Điểm mấu chốt: Biome parse source code một lần duy nhất thành Concrete Syntax Tree (CST), sau đó cả formatter lẫn linter đều dùng chung cây này. ESLint + Prettier phải parse riêng biệt — double parsing gây lãng phí thời gian đáng kể trên các codebase lớn.
5. Tính năng mới trong Biome v2.x (2026)
5.1. Type-aware linting
Từ v2.0, Biome hỗ trợ lint rules dựa trên type information. Rule đầu tiên và được yêu cầu nhiều nhất: noFloatingPromises.
// ❌ Biome sẽ báo lỗi — Promise không được await
async function fetchData() {
fetch('/api/users'); // noFloatingPromises: Promise returned but not awaited
}
// ✅ Đúng
async function fetchData() {
await fetch('/api/users');
}
5.2. Plugin system với GritQL
Biome v2.0 giới thiệu hệ thống plugin sử dụng GritQL — một query language cho code patterns. Bạn có thể viết custom lint rules mà không cần code Rust:
{
"plugins": ["./biome-plugins/no-console-in-prod.grit"]
}
// no-console-in-prod.grit
`console.$method($args)` where {
$method <: or { "log", "debug", "info" },
// Cho phép console.error và console.warn
}
5.3. Linter Domains — tự động bật rules theo dependencies
{
"linter": {
"domains": {
"react": "error",
"next": "warn",
"solid": "off"
}
}
}
Biome tự phát hiện package.json dependencies và gợi ý bật domain tương ứng. Nếu project dùng React, tất cả rules của domain react (JSX accessibility, hooks rules, v.v.) sẽ tự động được kích hoạt.
5.4. Embedded CSS + GraphQL trong JavaScript
// Biome v2.4 format và lint CSS-in-JS tự động
const Button = styled.button`
background: #e94560;
padding: 12px 24px;
border: none;
border-radius: 8px;
color: #fff;
cursor: pointer;
&:hover {
background: #c73854;
}
`;
// GraphQL queries cũng được lint + format
const GET_USERS = gql`
query GetUsers($limit: Int!) {
users(limit: $limit) {
id
name
email
}
}
`;
6. Migration từ ESLint + Prettier sang Biome
6.1. Migration tự ��ộng
# Biome tự đọc config ESLint/Prettier và chuyển đổi
npx @biomejs/biome migrate eslint --write
npx @biomejs/biome migrate prettier --write
Command migrate eslint sẽ đọc .eslintrc.* và map các rules tương ứng sang biome.json. Những rules không có tương đương sẽ được liệt kê để bạn review.
6.2. Chiến lược migration cho dự án lớn
graph LR
A["Phase 1
Formatter only"] --> B["Phase 2
Lint recommended"]
B --> C["Phase 3
Strict rules"]
C --> D["Phase 4
Remove ESLint"]
style A fill:#4CAF50,stroke:#fff,color:#fff
style B fill:#2c3e50,stroke:#fff,color:#fff
style C fill:#e94560,stroke:#fff,color:#fff
style D fill:#16213e,stroke:#fff,color:#fff
Lộ trình migration 4 giai đoạn cho dự án lớn
Phase 1 — Formatter only: Bật Biome formatter, tắt Prettier. Đây là bước an toàn nhất vì chỉ thay đổi formatting.
{
"formatter": { "enabled": true },
"linter": { "enabled": false }
}
Phase 2 — Lint recommended: Bật linter với rules recommended. Song song giữ ESLint cho Vue SFC nếu cần (Biome chưa hỗ trợ đầy đủ Vue SFC).
Phase 3 ��� Strict rules: Bật thêm rules strict, xử lý violations còn lại.
Phase 4 — Remove ESLint: Gỡ bỏ hoàn toàn ESLint + Prettier + các config packages.
# Dọn dẹp sau migration
npm uninstall eslint prettier eslint-config-prettier \
eslint-plugin-vue @typescript-eslint/eslint-plugin \
@typescript-eslint/parser
# Xóa config files cũ
rm .eslintrc.js .prettierrc .eslintignore .prettierignore
7. Tích hợp CI/CD và IDE
7.1. GitHub Actions
name: Code Quality
on: [push, pull_request]
jobs:
biome:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- name: Biome CI Check
run: npx biome ci .
7.2. VS Code Extension
Biome cung cấp extension chính thức cho VS Code với LSP server tích hợp:
// .vscode/settings.json
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
}
}
Format on save nhanh đến mức nào?
Biome format một file trong ~1-2ms (Prettier mất ~50-100ms). Với format-on-save, bạn sẽ không bao giờ cảm nhận được delay — file được format tức thì khi nhấn Ctrl+S.
8. Biome với Vue.js projects
Hạn chế với Vue SFC
Tính đến v2.4, Biome chưa hỗ trợ parse/lint/format phần <template> và <style> trong Vue Single File Components (.vue). Biome chỉ xử lý phần <script> và <script setup>. Hỗ trợ đầy đủ Vue SFC nằm trong roadmap 2026.
Chiến lược thực tế cho Vue projects:
- Dùng Biome cho tất cả file
.ts,.tsx,.json,.css - Giữ
eslint-plugin-vuechỉ cho file.vue(template rules) - Tắt Prettier hoàn toàn — Biome xử lý format cho non-Vue files
{
"files": {
"ignore": ["**/*.vue"]
},
"formatter": { "enabled": true },
"linter": { "enabled": true }
}
9. Benchmark thực tế trên monorepo
| Tác vụ | ESLint + Prettier | Biome | Tăng tốc |
|---|---|---|---|
| Lint 5.000 files TS | 22.4s | 0.5s | 45x |
| Format 5.000 files | 6.8s | 0.2s | 34x |
| CI check (lint + format) | 31.2s | 0.6s | 52x |
| IDE feedback (single file) | 50-100ms | 1-2ms | 50x |
| npm install (deps) | ~45MB (8 packages) | ~12MB (1 package) | 73% nhỏ hơn |
10. Tổng kết
Biome không chỉ là "ESLint + Prettier nhanh hơn" — nó đại diện cho một thế hệ mới của JavaScript tooling viết bằng system-level languages. Với tốc độ nhanh hơn 25-50 lần, một file cấu hình duy nhất, type-aware linting, plugin system GritQL, và hỗ trợ CSS/GraphQL tích hợp sẵn, Biome đang dần trở thành tiêu chuẩn mới cho code quality trong hệ sinh thái JavaScript/TypeScript.
Nếu bạn đang bắt đầu dự án mới — không có lý do gì để không dùng Biome. Nếu bạn đang maintain dự án cũ với ESLint + Prettier — migration path rất rõ ràng với command biome migrate. CI pipeline sẽ nhanh hơn, DX sẽ mượt hơn, và bạn sẽ bớt đi vài file config rải rác trong project root.
Nguồn tham khảo
Disclaimer: The opinions expressed in this blog are solely my own and do not reflect the views or opinions of my employer or any affiliated organizations. The content provided is for informational and educational purposes only and should not be taken as professional advice. While I strive to provide accurate and up-to-date information, I make no warranties or guarantees about the completeness, reliability, or accuracy of the content. Readers are encouraged to verify the information and seek independent advice as needed. I disclaim any liability for decisions or actions taken based on the content of this blog.