Biome Linting
Expert knowledge of Biome's linting capabilities, rule categories, and code quality enforcement for JavaScript and TypeScript projects.
Overview
Biome's linter provides fast, comprehensive code quality checks with a focus on correctness, performance, security, and best practices. It's designed to catch common bugs and enforce consistent code patterns.
Core Commands
Basic Linting
Check files without fixing
biome check .
Check and auto-fix
biome check --write .
Check specific files
biome check src/**/*.ts
CI mode (strict, fails on warnings)
biome ci .
Command Options
Verbose output
biome check --verbose .
JSON output
biome check --json .
Only lint (skip formatting)
biome lint .
Apply safe fixes only
biome check --write --unsafe=false .
Rule Categories
Accessibility (a11y)
Rules for web accessibility and WCAG compliance:
{ "linter": { "rules": { "a11y": { "recommended": true, "noAccessKey": "error", "noAriaHiddenOnFocusable": "error", "noAutofocus": "warn", "noBlankTarget": "error", "noPositiveTabindex": "error", "useAltText": "error", "useAnchorContent": "error", "useButtonType": "error", "useValidAriaProps": "error" } } } }
Common violations:
-
Missing alt text on images
-
Autofocus on form elements
-
Positive tabindex values
-
Links without content
-
Invalid ARIA properties
Complexity
Rules to reduce code complexity:
{ "linter": { "rules": { "complexity": { "recommended": true, "noBannedTypes": "error", "noExcessiveCognitiveComplexity": "warn", "noExtraBooleanCast": "error", "noMultipleSpacesInRegularExpressionLiterals": "error", "noUselessCatch": "error", "noUselessConstructor": "error", "noUselessEmptyExport": "error", "noUselessFragments": "error", "noUselessLabel": "error", "noUselessRename": "error", "noUselessSwitchCase": "error", "noWith": "error" } } } }
Correctness
Rules for code correctness and bug prevention:
{ "linter": { "rules": { "correctness": { "recommended": true, "noChildrenProp": "error", "noConstAssign": "error", "noConstantCondition": "error", "noConstructorReturn": "error", "noEmptyPattern": "error", "noGlobalObjectCalls": "error", "noInnerDeclarations": "error", "noInvalidConstructorSuper": "error", "noNewSymbol": "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" } } } }
Critical rules:
-
noUndeclaredVariables : Catch undeclared variables
-
noUnusedVariables : Remove unused code
-
noConstAssign : Prevent const reassignment
-
noUnreachable : Detect unreachable code
-
useIsNan : Use isNaN() for NaN checks
Performance
Rules for performance optimization:
{ "linter": { "rules": { "performance": { "recommended": true, "noAccumulatingSpread": "warn", "noDelete": "error" } } } }
Security
Rules for security best practices:
{ "linter": { "rules": { "security": { "recommended": true, "noDangerouslySetInnerHtml": "error", "noDangerouslySetInnerHtmlWithChildren": "error", "noGlobalEval": "error" } } } }
Critical security rules:
-
Prevent XSS via innerHTML
-
Block eval() usage
-
Detect security vulnerabilities
Style
Code style and consistency rules:
{ "linter": { "rules": { "style": { "recommended": true, "noArguments": "error", "noCommaOperator": "error", "noImplicitBoolean": "warn", "noNegationElse": "warn", "noNonNullAssertion": "warn", "noParameterAssign": "error", "noRestrictedGlobals": "error", "noShoutyConstants": "warn", "noUnusedTemplateLiteral": "error", "noVar": "error", "useBlockStatements": "warn", "useCollapsedElseIf": "warn", "useConst": "error", "useDefaultParameterLast": "error", "useEnumInitializers": "warn", "useExponentiationOperator": "error", "useFragmentSyntax": "error", "useNumericLiterals": "error", "useSelfClosingElements": "error", "useShorthandArrayType": "error", "useSingleVarDeclarator": "error", "useTemplate": "warn", "useWhile": "error" } } } }
Key style rules:
-
noVar : Use let/const instead of var
-
useConst : Prefer const for immutable bindings
-
noNonNullAssertion : Avoid ! assertions in TypeScript
-
useTemplate : Prefer template literals
Suspicious
Rules for suspicious code patterns:
{ "linter": { "rules": { "suspicious": { "recommended": true, "noArrayIndexKey": "warn", "noAssignInExpressions": "error", "noAsyncPromiseExecutor": "error", "noCatchAssign": "error", "noClassAssign": "error", "noCommentText": "error", "noCompareNegZero": "error", "noConsoleLog": "warn", "noControlCharactersInRegex": "error", "noDebugger": "error", "noDoubleEquals": "error", "noDuplicateCase": "error", "noDuplicateClassMembers": "error", "noDuplicateObjectKeys": "error", "noDuplicateParameters": "error", "noEmptyBlockStatements": "warn", "noExplicitAny": "warn", "noExtraNonNullAssertion": "error", "noFallthroughSwitchClause": "error", "noFunctionAssign": "error", "noGlobalAssign": "error", "noImportAssign": "error", "noLabelVar": "error", "noMisleadingCharacterClass": "error", "noPrototypeBuiltins": "error", "noRedeclare": "error", "noSelfCompare": "error", "noShadowRestrictedNames": "error", "noUnsafeNegation": "error", "useDefaultSwitchClauseLast": "error", "useGetterReturn": "error", "useValidTypeof": "error" } } } }
Critical suspicious patterns:
-
noExplicitAny : Avoid any in TypeScript
-
noConsoleLog : Remove console.log in production
-
noDebugger : Remove debugger statements
-
noDoubleEquals : Use === instead of ==
-
noDuplicateObjectKeys : Catch duplicate keys
Rule Configuration Patterns
Strict Configuration
Maximum strictness for high-quality codebases:
{ "linter": { "enabled": true, "rules": { "recommended": true, "a11y": { "recommended": true }, "complexity": { "recommended": true }, "correctness": { "recommended": true }, "performance": { "recommended": true }, "security": { "recommended": true }, "style": { "recommended": true }, "suspicious": { "recommended": true, "noExplicitAny": "error", "noConsoleLog": "error" } } } }
Gradual Adoption
Start lenient and progressively tighten:
{ "linter": { "enabled": true, "rules": { "recommended": true, "suspicious": { "noExplicitAny": "warn", "noConsoleLog": "warn" }, "style": { "noVar": "error", "useConst": "warn" } } } }
Framework-Specific
React configuration example:
{ "linter": { "rules": { "recommended": true, "a11y": { "recommended": true }, "correctness": { "recommended": true, "noChildrenProp": "error" }, "security": { "noDangerouslySetInnerHtml": "error" }, "suspicious": { "noArrayIndexKey": "error" } } } }
Ignoring Violations
Inline Comments
Suppress specific violations:
// biome-ignore lint/suspicious/noExplicitAny: Legacy code function legacyFunction(data: any) { return data; }
// biome-ignore lint/suspicious/noConsoleLog: Debug logging console.log('Debug info');
// Multiple rules // biome-ignore lint/suspicious/noExplicitAny lint/style/useConst: Migration var config: any = {};
File-Level Ignores
Ignore entire file:
/* biome-ignore-file */
// Legacy file, skip all linting
Configuration Ignores
Ignore patterns in biome.json:
{ "files": { "ignore": [ "/generated/", "/*.config.js", "/vendor/**" ] } }
Best Practices
-
Enable Recommended Rules - Start with "recommended": true
-
Progressive Enhancement - Add stricter rules gradually
-
Document Exceptions - Explain why rules are disabled
-
Use Inline Ignores Sparingly - Prefer fixing over ignoring
-
Security First - Never disable security rules
-
CI Enforcement - Use biome ci in pipelines
-
Pre-commit Hooks - Catch issues before commit
-
Team Agreement - Discuss rule changes with team
-
Regular Review - Periodically review disabled rules
-
Fix Warnings - Don't let warnings accumulate
Common Pitfalls
-
Ignoring Errors - Using biome-ignore instead of fixing
-
Disabling Security - Turning off security rules
-
No CI Check - Not enforcing in continuous integration
-
Too Lenient - Setting everything to "warn"
-
No Documentation - Not explaining disabled rules
-
Inconsistent Config - Different rules per package
-
Ignoring Warnings - Treating warnings as optional
-
Wrong Rule Names - Typos in rule configuration
-
Overly Strict - Blocking team productivity
-
No Migration Plan - Enabling all rules at once
Advanced Topics
Custom Rule Sets
Create shared rule sets for organization:
{ "extends": ["@company/biome-config"], "linter": { "rules": { "suspicious": { "noConsoleLog": "error" } } } }
Per-Directory Rules
Use overrides for different code areas:
{ "overrides": [ { "include": ["src//*.ts"], "linter": { "rules": { "suspicious": { "noExplicitAny": "error" } } } }, { "include": ["scripts//*.js"], "linter": { "rules": { "suspicious": { "noConsoleLog": "off" } } } } ] }
Migration Strategy
Migrating from ESLint:
-
Install Biome: npm install -D @biomejs/biome
-
Initialize: npx biome init
-
Run Check: npx biome check . to see violations
-
Fix Automatically: npx biome check --write .
-
Address Remaining: Fix issues that can't auto-fix
-
Tune Rules: Adjust rules based on team needs
-
Update CI: Replace ESLint with Biome
-
Remove ESLint: After validation period
Integration Patterns
Package.json Scripts
{ "scripts": { "lint": "biome check .", "lint:fix": "biome check --write .", "lint:ci": "biome ci ." } }
Pre-commit Hook
Using husky:
{ "husky": { "hooks": { "pre-commit": "biome check --write --changed" } } }
GitHub Actions
- name: Run Biome run: npx biome ci .
Troubleshooting
False Positives
If rule triggers incorrectly:
-
Verify rule is appropriate for your code
-
Check if bug in Biome (report upstream)
-
Use biome-ignore with explanation
-
Consider disabling rule if widespread
Performance Issues
If linting is slow:
-
Update to latest Biome version
-
Use VCS integration
-
Ignore large generated directories
-
Check for file pattern issues
Rules Not Applied
Verify:
-
Linter is enabled in config
-
Rule category is enabled
-
Rule name is spelled correctly
-
No overrides disabling it
-
Files are not ignored
When to Use This Skill
-
Setting up linting for new projects
-
Migrating from ESLint to Biome
-
Configuring rule sets for teams
-
Troubleshooting linting errors
-
Optimizing code quality checks
-
Establishing code standards
-
Training team on Biome linting
-
Integrating linting into CI/CD