
biome-config
by sgcarstrends
Monorepo for SG Cars Trends backend services
SKILL.md
name: biome-config description: Update Biome linting rules, formatting configs, and import organization settings. Use when adding new lint rules, customizing code style, or fixing workspace-specific linting issues. allowed-tools: Read, Edit, Bash, Grep, Glob
Biome Configuration Skill
This skill helps you configure and customize Biome for linting and formatting across the monorepo.
When to Use This Skill
- Adding new linting rules
- Customizing code formatting
- Configuring import organization
- Fixing linting errors across the codebase
- Setting up workspace-specific rules
- Debugging Biome configuration issues
- Migrating from ESLint/Prettier
Biome Overview
Biome is an all-in-one toolchain for web projects that provides:
- Linting: Fast, opinionated linting
- Formatting: Consistent code formatting
- Import Organization: Automatic import sorting
The project uses Biome instead of ESLint and Prettier for better performance.
Configuration Structure
sgcarstrends/
├── biome.json # Root Biome config
├── apps/
│ ├── api/
│ │ └── biome.json # API-specific config (extends root)
│ └── web/
│ └── biome.json # Web-specific config (extends root)
└── packages/
└── database/
└── biome.json # Database-specific config
Root Configuration
// biome.json
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true,
"defaultBranch": "main"
},
"files": {
"ignoreUnknown": false,
"ignore": [
"node_modules",
"dist",
"build",
".next",
".turbo",
"coverage",
".sst"
]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"lineEnding": "lf"
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"complexity": {
"noExtraBooleanCast": "error",
"noMultipleSpacesInRegularExpressionLiterals": "error",
"noUselessCatch": "error",
"noUselessConstructor": "error",
"noUselessEmptyExport": "error",
"noWith": "error"
},
"correctness": {
"noConstAssign": "error",
"noConstantCondition": "error",
"noEmptyCharacterClassInRegex": "error",
"noEmptyPattern": "error",
"noGlobalObjectCalls": "error",
"noInvalidConstructorSuper": "error",
"noInvalidNewBuiltin": "error",
"noNonoctalDecimalEscape": "error",
"noPrecisionLoss": "error",
"noSelfAssign": "error",
"noSetterReturn": "error",
"noSwitchDeclarations": "error",
"noUndeclaredVariables": "error",
"noUnreachable": "error",
"noUnreachableSuper": "error",
"noUnsafeFinally": "error",
"noUnsafeOptionalChaining": "error",
"noUnusedLabels": "error",
"noUnusedVariables": "error",
"useIsNan": "error",
"useValidForDirection": "error",
"useYield": "error"
},
"security": {
"noDangerouslySetInnerHtml": "error",
"noDangerouslySetInnerHtmlWithChildren": "error"
},
"style": {
"noArguments": "error",
"noVar": "error",
"useConst": "error",
"useTemplate": "error"
},
"suspicious": {
"noAsyncPromiseExecutor": "error",
"noCatchAssign": "error",
"noClassAssign": "error",
"noCommentText": "error",
"noCompareNegZero": "error",
"noDebugger": "error",
"noDoubleEquals": "error",
"noDuplicateCase": "error",
"noDuplicateClassMembers": "error",
"noDuplicateObjectKeys": "error",
"noDuplicateParameters": "error",
"noEmptyBlockStatements": "error",
"noExplicitAny": "warn",
"noExtraNonNullAssertion": "error",
"noFallthroughSwitchClause": "error",
"noFunctionAssign": "error",
"noGlobalAssign": "error",
"noImportAssign": "error",
"noMisleadingCharacterClass": "error",
"noMisleadingInstantiator": "error",
"noPrototypeBuiltins": "error",
"noRedeclare": "error",
"noShadowRestrictedNames": "error",
"noUnsafeDeclarationMerging": "error",
"noUnsafeNegation": "error",
"useGetterReturn": "error",
"useValidTypeof": "error"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"jsxQuoteStyle": "double",
"quoteProperties": "asNeeded",
"trailingCommas": "es5",
"semicolons": "always",
"arrowParentheses": "always",
"bracketSpacing": true,
"bracketSameLine": false
}
}
}
Workspace-Specific Configuration
Apps Configuration
// apps/web/biome.json
{
"extends": ["../../biome.json"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off" // Allow 'any' in web app for flexibility
}
}
}
}
Test Files Configuration
// Override for test files (if needed)
{
"overrides": [
{
"include": ["**/__tests__/**", "**/*.test.ts", "**/*.spec.ts"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off"
}
}
}
}
]
}
Common Commands
Check Code
# Check all files
pnpm biome check .
# Check specific directory
pnpm biome check apps/web
# Check and apply safe fixes
pnpm biome check --write .
# Check only linting
pnpm biome lint .
# Check only formatting
pnpm biome format .
Format Code
# Format all files
pnpm biome format --write .
# Format specific files
pnpm biome format --write apps/web/src/**/*.ts
# Check formatting without writing
pnpm biome format .
Organize Imports
# Organize imports
pnpm biome check --organize-imports-enabled=true --write .
CI Mode
# Check without modifying files (for CI)
pnpm biome ci .
Linting Rules
Enabling/Disabling Rules
Disable a rule globally:
{
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off"
}
}
}
}
Change severity:
{
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "warn" // error, warn, off
}
}
}
}
Disable inline:
// biome-ignore lint/suspicious/noExplicitAny: Legacy code needs refactoring
function legacy(data: any) {
// ...
}
Disable for entire file:
/* biome-ignore lint/suspicious/noExplicitAny: Test file */
Recommended Rules
Enable all recommended:
{
"linter": {
"rules": {
"recommended": true
}
}
}
Enable specific categories:
{
"linter": {
"rules": {
"recommended": false,
"correctness": {
"recommended": true
},
"security": {
"recommended": true
},
"performance": {
"recommended": true
}
}
}
}
Formatting Configuration
JavaScript/TypeScript
{
"javascript": {
"formatter": {
"quoteStyle": "double", // "single" or "double"
"jsxQuoteStyle": "double",
"quoteProperties": "asNeeded", // "asNeeded" or "preserve"
"trailingCommas": "es5", // "none", "es5", or "all"
"semicolons": "always", // "always" or "asNeeded"
"arrowParentheses": "always", // "always" or "asNeeded"
"bracketSpacing": true,
"bracketSameLine": false
}
}
}
Line Width and Indentation
{
"formatter": {
"indentStyle": "space", // "space" or "tab"
"indentWidth": 2, // Number of spaces
"lineWidth": 100, // Max line length
"lineEnding": "lf" // "lf", "crlf", or "cr"
}
}
Import Organization
Configuration
{
"organizeImports": {
"enabled": true
}
}
Import Groups
Biome automatically organizes imports into groups:
- Built-in modules (e.g.,
fs,path) - External modules (e.g.,
react,next) - Internal modules (e.g.,
@/components,~/utils) - Relative imports (e.g.,
./utils,../types)
Example:
// Before
import { Button } from "./components/button";
import { useState } from "react";
import path from "path";
import { db } from "@/lib/db";
// After
import path from "path";
import { useState } from "react";
import { db } from "@/lib/db";
import { Button } from "./components/button";
Git Integration
Git Hooks with Husky
Biome integrates with git hooks:
// .husky/pre-commit
pnpm biome check --write --staged
Git-Aware Processing
{
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true, // Respect .gitignore
"defaultBranch": "main"
}
}
Ignoring Files
Via Configuration
{
"files": {
"ignore": [
"node_modules",
"dist",
"build",
".next",
".turbo",
"coverage",
".sst",
"**/*.config.js",
"migrations/**"
]
}
}
Via .gitignore
With useIgnoreFile: true, Biome respects .gitignore.
Inline Ignore
// biome-ignore format: Auto-generated code
const generated = "...";
Package.json Scripts
{
"scripts": {
"lint": "biome check .",
"lint:fix": "biome check --write .",
"format": "biome format --write .",
"format:check": "biome format .",
"biome:ci": "biome ci ."
}
}
VS Code Integration
Install Extension
- Install "Biome" extension
- Configure as default formatter
Settings
// .vscode/settings.json
{
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
},
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
},
"[javascriptreact]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
},
"[json]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
},
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
}
}
Migration from ESLint/Prettier
1. Remove Old Tools
# Remove ESLint
pnpm remove -r eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
# Remove Prettier
pnpm remove -r prettier
# Remove config files
rm .eslintrc.json .prettierrc .prettierignore
2. Install Biome
# Already installed in project
pnpm add -D -w @biomejs/biome
3. Migrate Configuration
Convert ESLint rules to Biome:
- Check Biome documentation for equivalent rules
- Some rules may not have direct equivalents
- Use
biome migrate eslintfor automated migration
npx @biomejs/biome migrate eslint --write
4. Update Scripts
Replace in package.json:
{
"scripts": {
"lint": "biome check .", // was: eslint .
"format": "biome format --write ." // was: prettier --write .
}
}
Troubleshooting
Rule Conflicts
Issue: Rule seems to contradict another Solution: Check rule documentation, disable one if needed
Performance Issues
Issue: Biome is slow on large codebase Solutions:
- Check
files.ignoreis properly set - Run on specific directories
- Use
--max-diagnosticsto limit output
Format Not Applied
Issue: Files not formatting on save Solutions:
- Check VS Code extension is installed
- Verify
editor.defaultFormatteris set to Biome - Check
biome.jsonis in workspace root
Import Organization Not Working
Issue: Imports not organizing Solutions:
- Verify
organizeImports.enabled: true - Run explicitly:
biome check --organize-imports-enabled=true --write . - Check for syntax errors in file
Advanced Configuration
Per-File Overrides
{
"overrides": [
{
"include": ["**/*.config.ts"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off"
}
}
}
},
{
"include": ["apps/api/**/*.ts"],
"formatter": {
"lineWidth": 120
}
}
]
}
Custom Rule Severity
{
"linter": {
"rules": {
"correctness": {
"noUnusedVariables": "error"
},
"style": {
"useConst": "warn"
},
"suspicious": {
"noExplicitAny": "off"
}
}
}
}
CI Integration
GitHub Actions
# .github/workflows/lint.yml
name: Lint
on: [push, pull_request]
jobs:
biome:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"
- run: pnpm install
- run: pnpm biome ci .
References
- Biome Documentation: https://biomejs.dev
- Migration Guide: https://biomejs.dev/guides/migrate-eslint-prettier
- Rules Reference: https://biomejs.dev/linter/rules
- Related files:
biome.json- Root configuration- Root CLAUDE.md - Code style guidelines
Best Practices
- Use Root Config: Define common rules in root
biome.json - Extend in Workspaces: Extend root config for workspace-specific rules
- Git Integration: Enable VCS integration for
.gitignoresupport - Pre-commit Hooks: Run Biome on staged files
- CI Checks: Use
biome ciin continuous integration - Inline Ignores: Use sparingly and with clear comments
- Consistent Formatting: Apply formatting across entire codebase
- Regular Updates: Keep Biome updated for new rules and fixes
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
1ヶ月以内に更新
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon


