Skip to content

Biome

Biome is a fast, all-in-one toolchain for web projects written in Rust. It formats and lints JavaScript, TypeScript, JSX, TSX, JSON, and CSS files. A single Biome run is 25x faster than Prettier and replaces both ESLint and Prettier with zero configuration to start.

Installation

# npm
npm install --save-dev --save-exact @biomejs/biome

# pnpm
pnpm add --save-dev --save-exact @biomejs/biome

# yarn
yarn add --dev --exact @biomejs/biome

# Bun
bun add --dev --exact @biomejs/biome

# Initialize a config file
npx @biomejs/biome init

# Or via the Biome CLI (if installed globally)
npm install -g @biomejs/biome
biome init

# Check version
biome --version

VS Code Extension

Install the Biome extension from the VS Code Marketplace for format-on-save and inline diagnostics. Then add to .vscode/settings.json:

{
  "editor.defaultFormatter": "biomejs.biome",
  "editor.formatOnSave": true,
  "[javascript]": { "editor.defaultFormatter": "biomejs.biome" },
  "[typescript]": { "editor.defaultFormatter": "biomejs.biome" },
  "[json]": { "editor.defaultFormatter": "biomejs.biome" }
}

Configuration

Biome is configured via biome.json (or biome.jsonc for comments):

{
  "$schema": "https://biomejs.dev/schemas/1.8.0/schema.json",
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true,
    "defaultBranch": "main"
  },
  "files": {
    "include": ["src/**", "tests/**"],
    "ignore": ["dist/**", "node_modules/**", "*.min.js"],
    "ignoreUnknown": false
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100,
    "lineEnding": "lf",
    "attributePosition": "auto"
  },
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "a11y": {
        "recommended": true
      },
      "complexity": {
        "noForEach": "error",
        "useLiteralKeys": "error"
      },
      "correctness": {
        "noUnusedVariables": "warn",
        "noUnusedImports": "warn"
      },
      "style": {
        "useConst": "error",
        "useTemplate": "warn",
        "noVar": "error"
      },
      "suspicious": {
        "noConsoleLog": "warn",
        "noDebugger": "error"
      },
      "performance": {
        "noAccumulatingSpread": "warn"
      },
      "security": {
        "noDangerouslySetInnerHtml": "warn"
      }
    }
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single",
      "trailingCommas": "es5",
      "semicolons": "always",
      "arrowParentheses": "always",
      "bracketSpacing": true,
      "bracketSameLine": false,
      "jsxQuoteStyle": "double"
    },
    "globals": ["React", "__dirname", "__filename"]
  },
  "json": {
    "formatter": {
      "trailingCommas": "none"
    },
    "linter": {
      "rules": {
        "recommended": true
      }
    }
  },
  "css": {
    "formatter": {
      "enabled": true
    },
    "linter": {
      "enabled": true
    }
  }
}

Per-File Overrides

{
  "overrides": [
    {
      "include": ["**/*.test.ts", "**/*.spec.ts"],
      "linter": {
        "rules": {
          "suspicious": {
            "noConsoleLog": "off"
          }
        }
      }
    },
    {
      "include": ["scripts/**/*.js"],
      "javascript": {
        "globals": ["require", "process"]
      }
    }
  ]
}

Core Commands

CommandDescription
biome check .Lint, format check, and organize imports
biome check --write .Fix all auto-fixable issues
biome check --unsafe .Apply unsafe fixes too
biome format .Format files (show diff)
biome format --write .Format files in place
biome lint .Lint files (show diagnostics)
biome lint --write .Fix auto-fixable lint issues
biome lint --apply-unsafe .Apply unsafe lint fixes
biome ci .Run in CI mode (non-zero exit on any issue)
biome check --stdin-file-path=file.tsLint/format from stdin
biome format --stdin-file-path=file.tsFormat from stdin
biome migrateMigrate from ESLint/Prettier config
biome migrate eslint --writeMigrate ESLint rules to Biome
biome migrate prettier --writeMigrate Prettier config to Biome
biome ragePrint debug info for bug reports
biome versionShow version information
biome explain noUnusedVariablesExplain a specific rule
biome search "pattern" .Search code with GritQL patterns

Advanced Usage

Migrating from ESLint + Prettier

# Automated migration
biome migrate eslint --write
biome migrate prettier --write

# After migration, remove old tools
npm uninstall eslint prettier \
  eslint-config-prettier \
  eslint-plugin-prettier \
  @typescript-eslint/eslint-plugin \
  @typescript-eslint/parser

# Update scripts in package.json

Inline Suppression

// biome-ignore lint/style/useConst: this must be reassigned
let count = 0;

// biome-ignore lint/suspicious/noConsoleLog: debugging
console.log("value:", count);

// biome-ignore format: manually formatted table
const matrix = [
  1, 0, 0,
  0, 1, 0,
  0, 0, 1,
];

// biome-ignore lint/all: legacy code
function oldFunction() { /* ... */ }

Rule Categories

CategoryDescription
a11yAccessibility rules (ARIA, roles, labels)
complexityCode complexity and simplification
correctnessCatches likely bugs and mistakes
nurseryNew rules under development
performancePerformance anti-patterns
securitySecurity vulnerabilities
styleStylistic preferences
suspiciousSuspicious patterns (console.log, debugger)

Using with Git Hooks (lint-staged)

// package.json
{
  "lint-staged": {
    "*.{js,ts,jsx,tsx,json,css}": [
      "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true"
    ]
  }
}
# Install husky and lint-staged
npm install --save-dev husky lint-staged
npx husky init
echo "npx lint-staged" > .husky/pre-commit
# Search for console.log calls
biome search 'console.log($args)' src/

# Search for specific patterns
biome search 'var $name = $value' src/

# Works with JS, TS, JSX, TSX

Formatting via stdin (Editor Integration)

# Format a file piped through stdin
cat src/index.ts | biome format --stdin-file-path=index.ts

# Lint from stdin
cat src/index.ts | biome check --stdin-file-path=index.ts

Common Workflows

Initial Project Setup

# Install and init
pnpm add --save-dev --save-exact @biomejs/biome
npx @biomejs/biome init

# Add scripts to package.json
{
  "scripts": {
    "check": "biome check .",
    "check:fix": "biome check --write .",
    "format": "biome format --write .",
    "lint": "biome lint .",
    "lint:fix": "biome lint --write ."
  }
}

CI Integration

# GitHub Actions
name: Code Quality
on: [push, pull_request]
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
      - run: npx @biomejs/biome ci .

Checking a Single File

# Check specific file
biome check src/components/Button.tsx

# Format specific directory
biome format --write src/utils/

# Lint with verbose output
biome lint --verbose src/

Tips and Best Practices

Pin the exact version — Biome formats deterministically, but different versions may produce different output. Always pin with --save-exact and commit biome.json to version control.

Use biome check not separate commands — biome check runs formatting, linting, and import organization in one pass. It’s faster than running each separately and the correct command for most workflows.

Use biome ci in CI pipelines — biome ci is stricter than biome check: it exits with a non-zero status on any issue (including formatting differences) and never modifies files.

Enable VCS integration — Set "vcs": { "enabled": true, "useIgnoreFile": true } to respect your .gitignore. This prevents Biome from processing build artifacts and vendored files.

Prefer biome migrate — If switching from ESLint + Prettier, the migration command maps known ESLint rules to their Biome equivalents and sets up the biome.json. It’s faster than manual configuration.

Use biome explain to understand rules — biome explain noUnusedVariables prints the rule documentation with examples. Much faster than searching the docs.

Configure overrides for test files — Relax rules like noConsoleLog in test files using overrides. This avoids false positives in test utilities without disabling the rule globally.

Biome doesn’t need a cache — Unlike ESLint, Biome is fast enough that it doesn’t need a file-level cache. A full lint of 1,000 files takes milliseconds. Don’t add unnecessary complexity caching Biome results.