Fix: Biome Not Working — Rules Not Applied, ESLint Config Not Migrated, or VSCode Extension Ignored
Quick Answer
How to fix Biome linter/formatter issues — biome.json configuration, migrating from ESLint and Prettier, VSCode extension setup, CI integration, and rule override syntax.
The Problem
Biome runs but reports no errors on code that should fail:
biome check src/
# Checked 42 file(s) in 23ms
# Found 0 errors. ← But obvious issues existOr ESLint rules migrated to Biome don’t match:
biome migrate eslint --write
# Some rules could not be migrated: no-console, import/orderOr the VSCode extension isn’t formatting on save despite being installed:
// .vscode/settings.json
{
"editor.formatOnSave": true
}
// Files still format with Prettier instead of BiomeOr Biome and TypeScript disagree on valid code:
// Biome reports: noExplicitAny — but this is intentional
function serialize(value: any): string { ... }Why This Happens
Biome is a newer tool with different conventions from ESLint + Prettier:
- Rules are opt-in per group —
"recommended": trueenables recommended rules, but many useful rules require explicit enablement. Without configuring rule groups, most checks are disabled. - Biome has fewer rules than ESLint — some ESLint plugins (especially ecosystem-specific ones like
eslint-plugin-react-hooks,eslint-plugin-import) don’t have Biome equivalents yet. The migration tool marks these as unsupported. - VSCode uses
editor.defaultFormatter— to use Biome as the formatter in VSCode, you must set"editor.defaultFormatter": "biomejs.biome"explicitly, not just install the extension. - Biome linter and formatter are independent — disabling one doesn’t affect the other. If you only want the formatter (replacing Prettier), configure
"linter": { "enabled": false }.
Fix 1: Set Up biome.json Correctly
Biome is configured through biome.json at the project root:
# Initialize Biome in your project
npm install --save-dev --save-exact @biomejs/biome
npx biome init # Creates biome.json with defaults// biome.json — complete recommended setup
{
"$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true // Respect .gitignore for file selection
},
"files": {
"ignoreUnknown": false,
"ignore": [
"dist",
"build",
".next",
"node_modules",
"coverage",
"*.min.js",
"**/__generated__/**"
]
},
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "space", // "tab" or "space"
"indentWidth": 2,
"lineEnding": "lf", // "lf", "crlf", "cr"
"lineWidth": 100, // Print width (like Prettier's)
"attributePosition": "auto" // HTML/JSX attribute wrapping
},
"organizeImports": {
"enabled": true // Auto-sort imports
},
"linter": {
"enabled": true,
"rules": {
"recommended": true, // Enable all recommended rules
"correctness": {
"recommended": true,
"noUnusedVariables": "error",
"noUnusedImports": "error"
},
"suspicious": {
"recommended": true,
"noConsole": "warn" // Warn on console.log
},
"style": {
"recommended": true,
"useConst": "error",
"noVar": "error"
},
"performance": {
"recommended": true
},
"security": {
"recommended": true
},
"a11y": {
"recommended": true // Accessibility rules
},
"complexity": {
"recommended": true
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "single", // "single" or "double"
"jsxQuoteStyle": "double", // JSX attribute quotes
"quoteProperties": "asNeeded", // Only quote object keys when needed
"trailingCommas": "all", // "all", "es5", "none"
"semicolons": "always", // "always" or "asNeeded"
"arrowParentheses": "always", // "(x) => x" vs "x => x"
"bracketSpacing": true, // { key: value }
"bracketSameLine": false // JSX closing bracket position
},
"parser": {
"unsafeParameterDecoratorsEnabled": true // For Angular/NestJS decorators
}
}
}Fix 2: Migrate from ESLint and Prettier
# Migrate ESLint config to Biome (reads .eslintrc.* and eslint.config.*)
npx biome migrate eslint --write
# Migrate Prettier config to Biome (reads .prettierrc)
npx biome migrate prettier --write
# After migration, review the generated biome.json
# Check for "inspired" comments — these are approximate equivalentsManually map common ESLint rules to Biome:
| ESLint Rule | Biome Equivalent |
|---|---|
no-unused-vars | correctness/noUnusedVariables |
no-console | suspicious/noConsole |
prefer-const | style/useConst |
no-var | style/noVar |
eqeqeq | suspicious/noDoubleEquals |
no-shadow | correctness/noShadow |
react-hooks/rules-of-hooks | correctness/useHookAtTopLevel |
react-hooks/exhaustive-deps | correctness/useExhaustiveDependencies |
jsx-a11y/alt-text | a11y/useAltText |
Rules not yet in Biome — keep ESLint for these:
# If you need import/order, no-restricted-imports, or plugin-specific rules,
# run both tools: Biome for formatting + basic linting, ESLint for complex rules
# This is a common transition strategy// package.json — run both during transition
{
"scripts": {
"lint": "biome check . && eslint src --ext .ts,.tsx",
"format": "biome format --write ."
}
}Fix 3: Configure VSCode Extension
// .vscode/settings.json — enable Biome as the default formatter
{
// Set Biome as default for JS/TS files
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[javascriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[json]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[jsonc]": {
"editor.defaultFormatter": "biomejs.biome"
},
// Format and fix on save
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit", // Auto-fix safe issues on save
"source.organizeImports.biome": "explicit" // Sort imports on save
},
// Disable Prettier and ESLint for files Biome handles
"prettier.enable": false,
"eslint.enable": false // Or keep enabled if running both
}Verify the extension is using the right Biome binary:
// .vscode/settings.json
{
// Point to local Biome binary (avoids version mismatches)
"biome.lspBin": "./node_modules/@biomejs/biome/bin/biome"
}# Install Biome extension from VSCode marketplace
# Extension ID: biomejs.biome
# Test that Biome works from the CLI
npx biome check --apply src/Fix 4: Override Specific Rules per File or Directory
Disable rules for specific files or add exceptions:
// biome.json
{
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "error" // Default: error
}
}
},
"overrides": [
{
// Disable rules for test files
"include": ["**/*.test.ts", "**/*.spec.ts", "**/__tests__/**"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off" // Allow 'any' in tests
},
"correctness": {
"noUnusedVariables": "off" // Allow unused variables in tests
}
}
}
},
{
// Different formatting for Markdown
"include": ["**/*.md"],
"formatter": {
"lineWidth": 80
}
},
{
// Generated files — only format, don't lint
"include": ["src/generated/**"],
"linter": {
"enabled": false
}
}
]
}Inline suppression (like eslint-disable):
// Suppress a single rule for one line
// biome-ignore lint/suspicious/noExplicitAny: third-party type doesn't provide types
function serialize(value: any): string {
return JSON.stringify(value);
}
// Suppress the formatter for a block
// biome-ignore format: manually formatted for readability
const matrix = [
1, 0, 0,
0, 1, 0,
0, 0, 1,
];Fix 5: CI Integration
# GitHub Actions
jobs:
biome:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
# Check formatting and lint — fail on any issue
- run: npx biome ci .
# Equivalent to: biome check --error-on-warnings .
# Or use the official GitHub Action
- uses: biomejs/setup-biome@v2
with:
version: latest
- run: biome ci .// package.json — useful scripts
{
"scripts": {
"check": "biome check .", // Check without writing
"check:apply": "biome check --apply .", // Fix safe issues
"check:apply-all": "biome check --apply-unsafe .", // Fix all (may change semantics)
"format": "biome format --write .",
"lint": "biome lint .",
"ci": "biome ci ." // CI mode — no writes, exits with error code
}
}Pre-commit hook with lint-staged:
// package.json
{
"lint-staged": {
"*.{js,jsx,ts,tsx,json}": [
"biome check --apply --no-errors-on-unmatched"
]
}
}# Install and configure lint-staged + husky
npm install --save-dev lint-staged husky
npx husky init
echo "npx lint-staged" > .husky/pre-commitFix 6: Replace Prettier Completely
If replacing Prettier with Biome as the sole formatter:
# Remove Prettier and related packages
npm uninstall prettier @prettier/plugin-xml prettier-plugin-tailwindcss \
eslint-config-prettier eslint-plugin-prettier
# Remove Prettier config files
rm .prettierrc .prettierrc.js .prettierignore
# Update .editorconfig to match Biome settings (optional)// biome.json — Prettier-compatible settings
{
"formatter": {
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 80
},
"javascript": {
"formatter": {
"quoteStyle": "double", // Prettier default
"trailingCommas": "all", // Prettier default (ES5+)
"semicolons": "always",
"arrowParentheses": "always"
}
}
}Notable Biome formatting differences from Prettier:
- Biome adds trailing commas in function parameters (Prettier doesn’t in some cases)
- Biome handles long import statements differently in some edge cases
- Biome formats template literals slightly differently for multiline cases
- JSX formatting is generally compatible
Run biome format --write . then git diff to review all differences from Prettier before committing.
Still Not Working?
Biome ignores files that should be checked — verify biome.json is at the root of the project (same level as package.json). If biome.json is inside a subdirectory, Biome uses it only for that subdirectory. Run biome explain configuration to see which config file Biome is using.
biome check passes but CI fails — ensure the same Biome version is used locally and in CI. Add --exact when installing (npm install --save-dev --save-exact @biomejs/biome) to pin the version. Different Biome versions may have different rule sets.
VSCode extension shows errors that biome check doesn’t — the VSCode extension may be using a different Biome binary (global vs local) or a different config file. Set "biome.lspBin" in .vscode/settings.json to point to the local node_modules/.bin/biome binary.
TypeScript project references not supported — Biome doesn’t read tsconfig.json for type-aware linting (unlike typed ESLint rules like @typescript-eslint/no-floating-promises). Rules requiring type information are not available in Biome. If you rely heavily on typed ESLint rules, keep ESLint for those specific rules alongside Biome for formatting.
For related tooling issues, see Fix: ESLint Config Not Working and Fix: TypeScript Path Alias Not Working.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Clack Not Working — Prompts Not Displaying, Spinners Stuck, or Cancel Not Handled
How to fix @clack/prompts issues — interactive CLI prompts, spinners, multi-select, confirm dialogs, grouped tasks, cancellation handling, and building CLI tools with beautiful output.
Fix: CodeMirror Not Working — Editor Not Rendering, Extensions Not Loading, or React State Out of Sync
How to fix CodeMirror 6 issues — basic setup, language and theme extensions, React integration, vim mode, collaborative editing, custom keybindings, and read-only mode.
Fix: GSAP Not Working — Animations Not Playing, ScrollTrigger Not Firing, or React Cleanup Issues
How to fix GSAP animation issues — timeline and tween basics, ScrollTrigger setup, React useGSAP hook, cleanup and context, SplitText, stagger animations, and Next.js integration.
Fix: i18next Not Working — Translations Missing, Language Not Switching, or Namespace Errors
How to fix i18next issues — react-i18next setup, translation file loading, namespace configuration, language detection, interpolation, pluralization, and Next.js integration.