
Biome Linting
- 13 installs
- 213 repo stars
- Updated August 4, 2026
- yonatangross/orchestkit
Helps with code review & quality tasks.
About
biome-linting is a Claude Code skill for code review & quality. It helps solo builders move faster with AI-assisted coding.
- biome-linting
- Code Review & Quality
- AI-coding skill
Biome Linting by the numbers
- 13 all-time installs (skills.sh)
- Ranked #789 of 1,352 Code Review & Quality skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/yonatangross/orchestkit --skill biome-lintingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 13 |
|---|---|
| repo stars | ★ 213 |
| Last updated | August 4, 2026 |
| Repository | yonatangross/orchestkit ↗ |
What it does
Helps with code review & quality tasks.
Files
Biome Linting
Fast, unified linting and formatting (10-25x faster than ESLint + Prettier).
Why Biome in 2026
| Aspect | Biome | ESLint + Prettier |
|---|---|---|
| Speed | ~200ms for 10k lines | 3-5s |
| Config files | 1 (biome.json) | 4+ |
| npm packages | 1 binary | 127+ |
| Rules | 421 | Varies by plugins |
| Type inference | Yes (v2.0+) | Requires tsconfig |
Quick Start
# Install
npm install --save-dev --save-exact @biomejs/biome
# Initialize
npx @biomejs/biome init
# Check (lint + format)
npx @biomejs/biome check .
# Fix
npx @biomejs/biome check --write .
# CI mode (fails on errors)
npx @biomejs/biome ci .Biome 2.0 Features
Type Inference: Reads .d.ts from node_modules for type-aware rules:
{
"linter": {
"rules": {
"nursery": {
"noFloatingPromises": "error" // Catches unhandled promises
}
}
}
}Multi-file Analysis: Cross-module analysis for better diagnostics.
Basic Configuration
{
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"noUnusedVariables": "error",
"noUnusedImports": "error"
},
"suspicious": {
"noExplicitAny": "warn"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"trailingCommas": "all"
}
}
}ESLint Migration
# Auto-migrate configuration
npx @biomejs/biome migrate eslint --writeCommon Rule Mappings:
| ESLint | Biome |
|---|---|
| no-unused-vars | correctness/noUnusedVariables |
| no-console | suspicious/noConsole |
| @typescript-eslint/* | Most supported |
| eslint-plugin-react | Most supported |
| eslint-plugin-jsx-a11y | Most supported |
CI Integration
# .github/workflows/lint.yml
- uses: biomejs/setup-biome@v2
- run: biome ci .Overrides for Gradual Adoption
{
"overrides": [
{
"include": ["*.test.ts", "*.spec.ts"],
"linter": {
"rules": {
"suspicious": { "noExplicitAny": "off" }
}
}
},
{
"include": ["legacy/**"],
"linter": { "enabled": false }
}
]
}Key Decisions
| Decision | Recommendation |
|---|---|
| New vs migration | Biome first for new projects; migrate existing gradually |
| Config strictness | Start with recommended, tighten over time |
| CI strategy | Use biome ci for strict mode, biome check for local |
| Type inference | Enable for TypeScript projects (v2.0+) |
Related Skills
vite-advanced- Build tooling integrationreact-server-components-framework- React linting rulesci-cd-engineer- CI pipeline setup
References
- ESLint Migration - Step-by-step migration
- Biome Config - Full configuration options
- Type-Aware Rules - Biome 2.0 type inference
- CI Integration - GitHub Actions setup
ESLint to Biome Migration Checklist
Step-by-step verification for migration.
Pre-Migration
- [ ] Document current ESLint config
- [ ] List all ESLint plugins in use
- [ ] Identify critical rules that must be preserved
- [ ] Backup existing config files
- [ ] Note any custom rules
Installation
- [ ] Install Biome:
npm install -D --save-exact @biomejs/biome - [ ] Run init:
npx @biomejs/biome init - [ ] Run auto-migrate:
npx @biomejs/biome migrate eslint --write - [ ] Review generated
biome.json
Rule Mapping
Core ESLint Rules
- [ ]
no-unused-vars→correctness/noUnusedVariables - [ ]
no-console→suspicious/noConsole - [ ]
eqeqeq→suspicious/noDoubleEquals - [ ]
no-var→style/noVar - [ ]
prefer-const→style/useConst
TypeScript ESLint
- [ ]
@typescript-eslint/no-explicit-any→suspicious/noExplicitAny - [ ]
@typescript-eslint/no-unused-vars→correctness/noUnusedVariables - [ ]
@typescript-eslint/no-floating-promises→nursery/noFloatingPromises
React Rules
- [ ]
react-hooks/rules-of-hooks→correctness/useHookAtTopLevel - [ ]
react-hooks/exhaustive-deps→correctness/useExhaustiveDependencies - [ ]
react/jsx-no-duplicate-props→suspicious/noDuplicateJsxProps
Accessibility Rules
- [ ]
jsx-a11y/alt-text→a11y/useAltText - [ ]
jsx-a11y/anchor-is-valid→a11y/useValidAnchor
Formatting (Prettier Replacement)
- [ ] Configure
formattersection in biome.json - [ ] Set
indentStyle(tab/space) - [ ] Set
indentWidth - [ ] Set
lineWidth - [ ] Set
quoteStyle(single/double) - [ ] Set
trailingCommaspreference - [ ] Set
semicolonspreference
Editor Setup
VS Code
- [ ] Install Biome extension
- [ ] Update settings.json:
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
}- [ ] Disable ESLint extension (or set for specific workspaces)
- [ ] Disable Prettier extension
Other Editors
- [ ] Neovim: Configure LSP with biome
- [ ] WebStorm: Enable Biome support
CI/CD
- [ ] Update lint script:
"lint": "biome check ." - [ ] Update format script:
"format": "biome format --write ." - [ ] Update GitHub Actions workflow
- [ ] Update any pre-commit hooks
Testing
- [ ] Run
biome check .on full codebase - [ ] Compare output to previous ESLint output
- [ ] Fix any new issues found
- [ ] Run
biome format --write .to standardize formatting - [ ] Commit formatting changes in dedicated commit
Parallel Running Period
- [ ] Keep ESLint installed temporarily
- [ ] Run both:
npm run lint && npm run lint:eslint - [ ] Address discrepancies
- [ ] Monitor for missed issues
Cleanup
- [ ] Remove ESLint packages:
npm uninstall eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin \
eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y \
eslint-config-prettier eslint-plugin-prettier- [ ] Remove Prettier packages:
npm uninstall prettier eslint-config-prettier eslint-plugin-prettier- [ ] Delete config files:
rm -f .eslintrc* eslint.config.* .eslintignore .prettierrc* .prettierignore- [ ] Update README/docs
Verification
- [ ] All lint scripts work
- [ ] CI pipeline passes
- [ ] Format on save works in editor
- [ ] Pre-commit hooks work
- [ ] No regression in code quality
Post-Migration
- [ ] Document any rules not migrated
- [ ] Create issues for missing rule coverage
- [ ] Train team on Biome commands
- [ ] Update contributing guidelines
Biome Configuration Reference
Complete biome.json configuration options.
Schema
{
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json"
}Top-Level Structure
{
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
"formatter": { /* ... */ },
"linter": { /* ... */ },
"javascript": { /* ... */ },
"json": { /* ... */ },
"css": { /* ... */ },
"files": { /* ... */ },
"vcs": { /* ... */ },
"overrides": [ /* ... */ ]
}Formatter Configuration
{
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"lineEnding": "lf",
"formatWithErrors": false,
"ignore": ["**/dist/**"]
}
}| Option | Values | Default |
|---|---|---|
enabled | true, false | true |
indentStyle | "tab", "space" | "tab" |
indentWidth | 1-24 | 2 |
lineWidth | 1-320 | 80 |
lineEnding | "lf", "crlf", "cr" | "lf" |
Linter Configuration
{
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"noUnusedVariables": "error",
"noUnusedImports": "error"
},
"suspicious": {
"noExplicitAny": "warn",
"noConsole": "warn"
},
"style": {
"noVar": "error",
"useConst": "error",
"useTemplate": "warn"
},
"complexity": {
"noExcessiveCognitiveComplexity": {
"level": "warn",
"options": {
"maxAllowedComplexity": 15
}
}
},
"nursery": {
"noFloatingPromises": "error"
}
}
}
}Rule Levels
"off"- Disable the rule"warn"- Show warning, don't fail"error"- Show error, fail CI
Rule Categories
| Category | Description |
|---|---|
recommended | Enable all recommended rules |
correctness | Likely bugs and mistakes |
suspicious | Code that's likely wrong |
style | Code style issues |
complexity | Overly complex code |
performance | Performance issues |
security | Security vulnerabilities |
a11y | Accessibility issues |
nursery | Experimental rules |
JavaScript Configuration
{
"javascript": {
"formatter": {
"quoteStyle": "single",
"jsxQuoteStyle": "double",
"trailingCommas": "all",
"semicolons": "asNeeded",
"arrowParentheses": "always",
"quoteProperties": "asNeeded",
"bracketSpacing": true,
"bracketSameLine": false
},
"globals": ["React", "JSX"],
"parser": {
"unsafeParameterDecoratorsEnabled": false
}
}
}JSON Configuration
{
"json": {
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 80,
"trailingCommas": "none"
},
"parser": {
"allowComments": true,
"allowTrailingCommas": true
}
}
}CSS Configuration
{
"css": {
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 80,
"quoteStyle": "double"
},
"linter": {
"enabled": true
}
}
}Files Configuration
{
"files": {
"include": ["src/**/*.ts", "src/**/*.tsx"],
"ignore": [
"node_modules",
"dist",
"build",
".next",
"coverage",
"*.min.js"
],
"ignoreUnknown": true,
"maxSize": 1048576
}
}VCS Integration
{
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true,
"root": ".",
"defaultBranch": "main"
}
}Overrides
Apply different settings to specific files:
{
"overrides": [
{
"include": ["*.test.ts", "*.spec.ts", "**/__tests__/**"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off"
}
}
}
},
{
"include": ["scripts/**"],
"linter": {
"enabled": false
}
},
{
"include": ["*.config.js", "*.config.ts"],
"formatter": {
"lineWidth": 120
}
}
]
}Extends (2.0+)
Extend from other configurations:
{
"extends": ["./biome-base.json"]
}Biome CI Integration
Setting up Biome in CI/CD pipelines.
GitHub Actions
Basic Workflow
# .github/workflows/lint.yml
name: Code Quality
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Biome
uses: biomejs/setup-biome@v2
with:
version: latest
- name: Run Biome
run: biome ci .With Node.js
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run Biome
run: npx biome ci .Combined with Tests
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
# Run in parallel
- name: Lint
run: npx biome ci .
- name: Type Check
run: npx tsc --noEmit
- name: Test
run: npm testPre-commit Hooks
With Lefthook
# lefthook.yml
pre-commit:
commands:
biome:
glob: '*.{js,ts,jsx,tsx,json,css}'
run: npx biome check --write {staged_files}
stage_fixed: trueWith Husky + lint-staged
npm install -D husky lint-staged
npx husky init// package.json
{
"lint-staged": {
"*.{js,ts,jsx,tsx}": [
"biome check --write"
],
"*.{json,css}": [
"biome format --write"
]
}
}# .husky/pre-commit
npx lint-stagedGitLab CI
# .gitlab-ci.yml
lint:
image: node:20
script:
- npm ci
- npx biome ci .
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCHCLI Commands for CI
biome ci
Strict mode for CI environments:
# Fails on any error or warning
biome ci .
# Same as:
biome check --max-diagnostics=0 .biome check
More control over output:
# Check with specific max diagnostics
biome check --max-diagnostics=20 .
# Check specific files
biome check src/
# With specific config
biome check --config-path=./biome.json .Formatting Only
# Check formatting (no fix)
biome format --check .
# Fix formatting
biome format --write .Linting Only
# Lint only (no format)
biome lint .
# Lint with auto-fix
biome lint --write .Exit Codes
| Code | Meaning |
|---|---|
0 | Success |
1 | Errors found |
2 | Invalid arguments |
3 | Config error |
Performance Tips
Parallel Execution
Biome is multi-threaded by default. For large repos:
# Limit threads if needed
BIOME_MAX_THREADS=4 biome ci .Caching
# GitHub Actions with caching
- name: Cache Biome
uses: actions/cache@v4
with:
path: ~/.cache/biome
key: biome-${{ hashFiles('biome.json') }}Reporter Options
# Default: human-readable
biome ci .
# JSON output for parsing
biome ci --reporter=json .
# GitHub Actions annotations
biome ci --reporter=github .
# Summary only
biome ci --reporter=summary .Integration with PR Comments
- name: Run Biome
id: biome
run: npx biome ci --reporter=json . > biome-results.json
continue-on-error: true
- name: Comment on PR
if: failure()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs')
const results = JSON.parse(fs.readFileSync('biome-results.json', 'utf8'))
// Process and commentESLint to Biome Migration
Step-by-step guide for migrating from ESLint + Prettier.
Quick Migration
# Auto-migrate existing ESLint config
npx @biomejs/biome migrate eslint --write
# Preview changes without writing
npx @biomejs/biome migrate eslintThis reads your .eslintrc.* or eslint.config.js and creates biome.json.
Manual Migration Steps
1. Install Biome
# Install as dev dependency
npm install --save-dev --save-exact @biomejs/biome
# Or with other package managers
pnpm add -D -E @biomejs/biome
yarn add -D -E @biomejs/biome
bun add -D -E @biomejs/biome2. Initialize Configuration
npx @biomejs/biome initThis creates a basic biome.json.
3. Map ESLint Rules
| ESLint Rule | Biome Equivalent |
|---|---|
no-unused-vars | correctness/noUnusedVariables |
no-console | suspicious/noConsole |
eqeqeq | suspicious/noDoubleEquals |
no-debugger | suspicious/noDebugger |
no-empty | suspicious/noEmptyBlockStatements |
no-extra-boolean-cast | complexity/noExtraBooleanCast |
no-var | style/noVar |
prefer-const | style/useConst |
prefer-template | style/useTemplate |
4. Map TypeScript ESLint Rules
| TypeScript ESLint | Biome Equivalent |
|---|---|
@typescript-eslint/no-explicit-any | suspicious/noExplicitAny |
@typescript-eslint/no-unused-vars | correctness/noUnusedVariables |
@typescript-eslint/no-non-null-assertion | style/noNonNullAssertion |
@typescript-eslint/prefer-as-const | style/useAsConstAssertion |
@typescript-eslint/no-floating-promises | nursery/noFloatingPromises |
5. Map React Rules
| ESLint React | Biome Equivalent |
|---|---|
react/jsx-no-duplicate-props | suspicious/noDuplicateJsxProps |
react/no-children-prop | correctness/noChildrenProp |
react/void-dom-elements-no-children | correctness/noVoidElementsWithChildren |
react-hooks/rules-of-hooks | correctness/useHookAtTopLevel |
react-hooks/exhaustive-deps | correctness/useExhaustiveDependencies |
6. Map Accessibility Rules
| ESLint JSX A11y | Biome Equivalent |
|---|---|
jsx-a11y/alt-text | a11y/useAltText |
jsx-a11y/anchor-is-valid | a11y/useValidAnchor |
jsx-a11y/click-events-have-key-events | a11y/useKeyWithClickEvents |
jsx-a11y/no-autofocus | a11y/noAutofocus |
7. Transition Period
Run both linters in parallel during migration:
{
"scripts": {
"lint": "biome check .",
"lint:legacy": "eslint .",
"lint:compare": "npm run lint && npm run lint:legacy"
}
}8. Handle Unsupported Rules
Use overrides to disable Biome for files with unsupported patterns:
{
"overrides": [
{
"include": ["legacy/**"],
"linter": {
"enabled": false
}
}
]
}9. Remove ESLint
Once migration is complete:
# Remove ESLint packages
npm uninstall eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin \
eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y \
eslint-config-prettier eslint-plugin-prettier prettier
# Remove config files
rm .eslintrc* eslint.config.* .eslintignore .prettierrc* .prettierignoreVS Code Setup
Update .vscode/settings.json:
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
},
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
}
}Common Migration Issues
Rule Not Available
Some ESLint rules don't have Biome equivalents. Check the Biome rules reference or disable in Biome's config.
Different Behavior
Some rules behave slightly differently. Test thoroughly after migration.
Plugin Rules
Framework-specific plugin rules may not all be available. Check Biome's roadmap for planned support.
Biome 2.0 Type-Aware Rules
Leveraging TypeScript type inference for better linting.
How Type Inference Works
Biome 2.0 reads .d.ts files from node_modules to infer types without requiring tsconfig.json. This enables type-aware lint rules similar to typescript-eslint.
Key Type-Aware Rules
noFloatingPromises
Catches unhandled promises:
// ❌ Error: Promise not awaited or handled
async function fetchData() {
return { data: 'example' }
}
fetchData() // Floating promise!
// ✅ Correct
await fetchData()
fetchData().catch(console.error)
void fetchData() // Explicitly ignoredConfiguration:
{
"linter": {
"rules": {
"nursery": {
"noFloatingPromises": "error"
}
}
}
}noMisusedPromises
Prevents passing promises where non-promises expected:
// ❌ Error: Promise passed to boolean context
const items = [1, 2, 3]
items.filter(async (item) => {
const result = await checkItem(item)
return result // This returns Promise<boolean>, not boolean!
})
// ✅ Correct: Use regular function and await inside Promise.all
const results = await Promise.all(items.map(checkItem))
const filtered = items.filter((_, i) => results[i])noVoidTypeReturn
Prevents returning value from void functions:
// ❌ Error: Returning value from void function
function logMessage(msg: string): void {
console.log(msg)
return msg // Shouldn't return from void function
}Configuring Type Inference
{
"javascript": {
"parser": {
// Enable if using decorators without emitDecoratorMetadata
"unsafeParameterDecoratorsEnabled": false
}
},
"linter": {
"rules": {
"nursery": {
"noFloatingPromises": "error"
}
}
}
}Coverage Comparison
| Rule | Biome 2.0 Coverage | typescript-eslint |
|---|---|---|
| noFloatingPromises | ~85% | 100% |
| noMisusedPromises | ~80% | 100% |
| Type-narrowing | Partial | Full |
Biome's type inference covers common cases but may miss complex generics or conditional types.
When Type Rules Don't Apply
Biome won't infer types for:
1. Dynamic imports without type annotations 2. Complex generic inference 3. Conditional types with deep nesting 4. Files not in include patterns
Performance Considerations
Type inference adds overhead:
{
"files": {
// Limit type inference scope
"include": ["src/**/*.ts", "src/**/*.tsx"],
"ignore": ["**/*.js", "**/*.mjs"]
}
}Gradual Adoption
Start with warnings, then escalate:
{
"linter": {
"rules": {
"nursery": {
// Start as warning
"noFloatingPromises": "warn"
}
}
}
}After fixing issues:
{
"linter": {
"rules": {
"nursery": {
// Promote to error
"noFloatingPromises": "error"
}
}
}
}Multi-File Analysis
Biome 2.0 supports cross-file analysis for:
- Import/export validation
- Type references across modules
- Dead code detection across files
This is still evolving; check Biome release notes for updates.
Best Practices
1. Enable gradually: Start with warnings in CI 2. Focus on high-value rules: noFloatingPromises catches real bugs 3. Pair with TypeScript: Biome complements, doesn't replace tsc 4. Monitor performance: Type inference adds CPU time 5. Keep dependencies typed: Ensure packages have types
{
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 80,
"lineEnding": "lf",
"formatWithErrors": false
},
"linter": {
"enabled": true,
"rules": {
"all": true,
"correctness": {
"noUnusedVariables": "error",
"noUnusedImports": "error",
"noUnusedPrivateClassMembers": "error",
"useHookAtTopLevel": "error",
"useExhaustiveDependencies": "error"
},
"suspicious": {
"noExplicitAny": "error",
"noConsole": "error",
"noDebugger": "error",
"noDoubleEquals": "error",
"noEmptyBlockStatements": "error",
"noConfusingVoidType": "error",
"noAssignInExpressions": "error"
},
"style": {
"noVar": "error",
"useConst": "error",
"useTemplate": "error",
"useImportType": "error",
"useShorthandFunctionType": "error",
"useSingleVarDeclarator": "error",
"useExportType": "error"
},
"complexity": {
"noExcessiveCognitiveComplexity": {
"level": "error",
"options": {
"maxAllowedComplexity": 10
}
},
"noForEach": "warn",
"useFlatMap": "error"
},
"performance": {
"noAccumulatingSpread": "error",
"noDelete": "warn"
},
"security": {
"noDangerouslySetInnerHtml": "error",
"noGlobalEval": "error"
},
"a11y": {
"useAltText": "error",
"useValidAnchor": "error",
"useKeyWithClickEvents": "error",
"useButtonType": "error",
"noAutofocus": "warn"
},
"nursery": {
"noFloatingPromises": "error"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"jsxQuoteStyle": "double",
"trailingCommas": "all",
"semicolons": "asNeeded",
"arrowParentheses": "always"
}
},
"files": {
"ignore": [
"node_modules",
"dist",
"build",
".next",
"coverage"
]
},
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
}
}
{
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"lineEnding": "lf"
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"noUnusedVariables": "error",
"noUnusedImports": "error",
"useHookAtTopLevel": "error",
"useExhaustiveDependencies": "warn"
},
"suspicious": {
"noExplicitAny": "warn",
"noConsole": "warn",
"noDebugger": "error",
"noDoubleEquals": "error"
},
"style": {
"noVar": "error",
"useConst": "error",
"useTemplate": "warn",
"useImportType": "warn"
},
"complexity": {
"noExcessiveCognitiveComplexity": {
"level": "warn",
"options": {
"maxAllowedComplexity": 15
}
}
},
"a11y": {
"useAltText": "error",
"useValidAnchor": "error",
"useKeyWithClickEvents": "warn"
},
"nursery": {
"noFloatingPromises": "error"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"jsxQuoteStyle": "double",
"trailingCommas": "all",
"semicolons": "asNeeded",
"arrowParentheses": "always",
"bracketSpacing": true,
"bracketSameLine": false
}
},
"json": {
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"trailingCommas": "none"
},
"parser": {
"allowComments": true
}
},
"css": {
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"linter": {
"enabled": true
}
},
"files": {
"ignore": [
"node_modules",
"dist",
"build",
".next",
"coverage",
"*.min.js",
"*.d.ts"
],
"ignoreUnknown": true
},
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"overrides": [
{
"include": ["*.test.ts", "*.spec.ts", "**/__tests__/**"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off"
}
}
}
},
{
"include": ["*.config.js", "*.config.ts", "*.config.mjs"],
"linter": {
"rules": {
"suspicious": {
"noConsole": "off"
}
}
}
}
]
}
# Biome Linting GitHub Action
# Copy to .github/workflows/lint.yml
name: Code Quality
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
name: Biome Lint & Format
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Biome
uses: biomejs/setup-biome@v2
with:
version: latest
- name: Run Biome
run: biome ci .
# Alternative: Run via Node.js
lint-node:
name: Lint (Node.js)
runs-on: ubuntu-latest
if: false # Enable if you prefer npm-based setup
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run Biome
run: npx biome ci .
# Full quality pipeline
quality:
name: Full Quality Check
runs-on: ubuntu-latest
if: false # Enable for full pipeline
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
# Parallel quality checks
- name: Biome (Lint + Format)
run: npx biome ci .
- name: TypeScript
run: npx tsc --noEmit
- name: Tests
run: npm test -- --coverage
# Upload coverage (optional)
- name: Upload Coverage
uses: codecov/codecov-action@v4
if: always()
with:
files: coverage/lcov.info
# Notes:
# - `biome ci` is strict mode (fails on any warning/error)
# - For PR annotations, add `--reporter=github`
# - For JSON output, add `--reporter=json > biome-results.json`