Loading...
Loading...
Biome linter and formatter for JavaScript/TypeScript. Covers configuration, rules, and integration patterns. Replaces ESLint + Prettier for faster development experience. USE WHEN: user mentions "biome", "linting", "formatting", "code style", "biome.json", asks about "setup linter", "format code", "migrate from ESLint", "migrate from Prettier", "biome rules", "biome configuration" DO NOT USE FOR: ESLint configuration - Biome is an ESLint replacement, Prettier configuration - Biome is a Prettier replacement, TypeScript compilation - use TypeScript compiler, Code quality principles - use `clean-code` skill
npx skill4agent add claude-dev-suite/claude-dev-suite biomeDeep Knowledge: Usewith technology:mcp__documentation__fetch_docsfor comprehensive documentation.biome
tscclean-code| Anti-Pattern | Why It's Bad | Biome Best Practice |
|---|---|---|
| Disabling recommended rules | Misses important issues | Keep recommended, customize only what's needed |
| Ignoring all warnings | Warnings indicate real issues | Fix warnings or suppress with reason |
| No CI integration | Issues slip through | Use |
| Manual formatting | Inconsistent, waste time | Use format on save + pre-commit hooks |
| Mixing ESLint + Biome | Conflicting rules, confusion | Fully migrate to Biome or stay with ESLint |
| No VS Code integration | Manual CLI runs | Install Biome extension, enable format on save |
| Ignoring complexity rules | Allows unmaintainable code | Set cognitive complexity limits |
| Committing formatting issues | Messy diffs | Use pre-commit hooks with lint-staged |
| Issue | Check | Solution |
|---|---|---|
| Biome not formatting | VS Code extension installed? | Install |
| Format on save not working | Settings.json configured? | Add |
| Rules not applying | biome.json syntax valid? | Run |
| Too many warnings | Rules too strict? | Adjust severity levels or disable specific rules |
| CI failing | Different results locally? | Ensure same Biome version, check ignore patterns |
| Conflicts with Prettier | Both running? | Remove Prettier, Biome replaces it |
| Slow on large codebase | Checking too many files? | Add ignore patterns in biome.json |
| Can't migrate from ESLint | Complex config? | Use |
npm install --save-dev @biomejs/biome
# Initialize configuration
npx @biomejs/biome init{
"$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"complexity": {
"noExcessiveCognitiveComplexity": {
"level": "warn",
"options": {
"maxAllowedComplexity": 15
}
}
},
"correctness": {
"noUnusedVariables": "warn",
"noUnusedImports": "warn",
"useExhaustiveDependencies": "warn"
},
"style": {
"noNonNullAssertion": "off",
"useImportType": "warn"
},
"suspicious": {
"noExplicitAny": "warn"
}
}
},
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"trailingCommas": "es5",
"semicolons": "always"
}
},
"files": {
"ignore": [
"node_modules",
"dist",
"build",
".next",
"coverage",
"*.gen.ts"
]
}
}{
"scripts": {
"lint": "biome check .",
"lint:fix": "biome check --write .",
"format": "biome format --write .",
"check": "biome check --write --unsafe ."
}
}| Rule | Level | Description |
|---|---|---|
| warn | Flag unused variables |
| warn | Flag unused imports |
| warn | Discourage |
| warn | Check React hook deps |
| off | Allow |
| warn | Prefer |
// .vscode/settings.json
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
}
}# Install husky
npm install --save-dev husky lint-staged
# package.json
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"biome check --write --no-errors-on-unmatched"
]
}
}# Biome can migrate your config
npx @biomejs/biome migrate eslint --write
npx @biomejs/biome migrate prettier --write# Check all files
biome check .
# Fix issues
biome check --write .
# Format only
biome format --write .
# Lint only
biome lint .
# Check specific files
biome check src/components/**/*.tsx
# CI mode (exit with error)
biome ci .// Ignore next line
// biome-ignore lint/suspicious/noExplicitAny: needed for legacy API
const data: any = await fetch('/api');
// Ignore whole file (at top)
// biome-ignore-all lint/style/useImportType{
"$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"a11y": {
"recommended": true
},
"complexity": {
"noExcessiveCognitiveComplexity": {
"level": "error",
"options": { "maxAllowedComplexity": 15 }
},
"noExcessiveNestedTestSuites": "warn"
},
"correctness": {
"noUnusedVariables": "error",
"noUnusedImports": "error",
"useExhaustiveDependencies": "error"
},
"performance": {
"noAccumulatingSpread": "warn",
"noDelete": "warn"
},
"security": {
"noDangerouslySetInnerHtml": "error",
"noGlobalEval": "error"
},
"suspicious": {
"noExplicitAny": "warn",
"noConsoleLog": "warn"
}
}
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"trailingCommas": "es5",
"semicolons": "always"
}
},
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
}
}# .github/workflows/lint.yml
name: Lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- name: Biome CI
run: npx @biomejs/biome ci .
# Or with caching
- name: Cache Biome
uses: actions/cache@v4
with:
path: ~/.cache/biome
key: ${{ runner.os }}-biome-${{ hashFiles('biome.json') }}
- name: Check
run: npx @biomejs/biome check --diagnostic-level=error .// package.json
{
"scripts": {
"prepare": "husky install",
"lint": "biome check .",
"lint:fix": "biome check --write .",
"lint:ci": "biome ci ."
},
"lint-staged": {
"*.{js,jsx,ts,tsx,json}": [
"biome check --write --no-errors-on-unmatched --files-ignore-unknown=true"
]
}
}# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged// biome.json - Configure severity levels
{
"linter": {
"rules": {
// Block CI on these
"correctness": {
"noUnusedVariables": "error",
"useExhaustiveDependencies": "error"
},
// Allow in development, fail in CI
"suspicious": {
"noConsoleLog": {
"level": "warn",
"options": {}
}
}
}
}
}
// Stricter CI check
// package.json
{
"scripts": {
"lint:dev": "biome check .",
"lint:ci": "biome check --diagnostic-level=error --max-diagnostics=50 ."
}
}// vitest.config.ts - Run biome before tests
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globalSetup: './src/test/global-setup.ts',
},
});
// src/test/global-setup.ts
import { execSync } from 'child_process';
export default function setup() {
try {
execSync('npx @biomejs/biome check .', { stdio: 'pipe' });
} catch (error) {
console.error('Biome check failed. Fix linting issues before running tests.');
process.exit(1);
}
}| Metric | Target |
|---|---|
| Lint errors | 0 |
| Warnings | < 10 |
| Format issues | 0 |
| Cognitive complexity | < 15 |