Claude Code for Biome: Fast Linting and Formatting for JavaScript — Claude Skills 360 Blog
Blog / DevOps / Claude Code for Biome: Fast Linting and Formatting for JavaScript
DevOps

Claude Code for Biome: Fast Linting and Formatting for JavaScript

Published: February 10, 2027
Read time: 7 min read
By: Claude Skills 360

Biome is a Rust-based toolchain that combines a linter and formatter for JavaScript, TypeScript, JSX, and JSON — replacing ESLint and Prettier with a single tool that runs 25–100x faster. A single biome.json configures both lint rules and formatting options. biome check --write applies all safe fixes in one pass. biome lint --apply-unsafe applies transformations that may change semantics. The recommended rule set covers 200+ lint rules. biome migrate eslint converts existing ESLint configurations. Biome’s formatter is intentionally opinionated with fewer configuration options than Prettier, ensuring consistent output across teams. The --ci flag returns a non-zero exit code on any issue, blocking merges without --write. Claude Code generates Biome configurations, CI lint commands, pre-commit hook setups, and the monorepo override patterns for production JavaScript toolchains.

CLAUDE.md for Biome Projects

## Biome Stack
- Version: @biomejs/biome >= 1.9
- Config: biome.json at project root — one file for lint + format
- Check: biome check --write (fix) or biome check (report only)
- CI: biome ci — error on any issue, no fix
- Migrate: biome migrate eslint --write (from ESLint), biome migrate prettier (from Prettier)
- Monorepo: extends field in nested biome.json for workspace overrides
- VS Code: Biome extension (biomejs.biome) — set as default formatter

biome.json Configuration

{
  "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": {
        "noUnusedVariables": "error",
        "noUnusedImports": "error",
        "useExhaustiveDependencies": "error",
        "useHookAtTopLevel": "error"
      },
      "style": {
        "useConst": "error",
        "useTemplate": "warn",
        "noVar": "error",
        "useSingleVarDeclarator": "off",
        "noNonNullAssertion": "warn",
        "useImportType": "error"
      },
      "suspicious": {
        "noConsoleLog": "warn",
        "noExplicitAny": "warn",
        "noDoubleEquals": "error"
      },
      "performance": {
        "noAccumulatingSpread": "warn"
      },
      "security": {
        "noDangerouslySetInnerHtml": "warn"
      },
      "a11y": {
        "useButtonType": "error",
        "useAltText": "error"
      },
      "complexity": {
        "noBannedTypes": "error",
        "noForEach": "off"
      }
    }
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100,
    "lineEnding": "lf"
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "double",
      "semicolons": "asNeeded",
      "trailingCommas": "all",
      "arrowParentheses": "asNeeded",
      "bracketSpacing": true
    },
    "linter": {
      "enabled": true
    },
    "globals": ["__dirname", "__filename"]
  },
  "json": {
    "formatter": {
      "enabled": true,
      "trailingCommas": "none"
    }
  },
  "files": {
    "ignore": [
      "node_modules",
      "dist",
      ".next",
      ".astro",
      "coverage",
      "*.min.js",
      "public/assets"
    ]
  }
}

package.json Scripts

{
  "scripts": {
    "lint": "biome lint --write .",
    "lint:check": "biome lint .",
    "format": "biome format --write .",
    "format:check": "biome format .",
    "check": "biome check --write .",
    "check:ci": "biome ci ."
  },
  "devDependencies": {
    "@biomejs/biome": "^1.9.4"
  }
}

CI Integration

# .github/workflows/lint.yml — Biome in CI
name: Lint

on:
  push:
    branches: [main]
  pull_request:

jobs:
  biome:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Biome
        uses: biomejs/setup-biome@v2
        with:
          version: latest

      # biome ci: exits with error if any lint or format issues found
      # Does NOT auto-fix — use biome check --write locally
      - name: Run Biome CI
        run: biome ci .

Pre-commit Hook with Lefthook

# lefthook.yml — fast pre-commit linting
pre-commit:
  parallel: true
  commands:
    biome:
      glob: "*.{js,ts,jsx,tsx,json}"
      run: biome check --write --no-errors-on-unmatched {staged_files}
      stage_fixed: true  # Re-stage auto-fixed files

Monorepo Override

// packages/ui/biome.json — override for UI package
{
  "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
  "extends": ["../../biome.json"],
  "linter": {
    "rules": {
      "a11y": {
        // Stricter a11y in UI components
        "useButtonType": "error",
        "useAltText": "error",
        "useAriaProps": "error",
        "noRedundantAlt": "error"
      },
      "security": {
        // Allow dangerouslySetInnerHTML in UI (sanitized externally)
        "noDangerouslySetInnerHtml": "off"
      }
    }
  }
}
// apps/backend/biome.json — different rules for Node.js backend
{
  "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
  "extends": ["../../biome.json"],
  "linter": {
    "rules": {
      "suspicious": {
        // Allow console.log in backend
        "noConsoleLog": "off"
      },
      "security": {
        // Not relevant in backend components
        "noDangerouslySetInnerHtml": "off"
      }
    }
  }
}

Migrate from ESLint + Prettier

# Migration script — converts ESLint config to Biome equivalents
npx @biomejs/biome migrate eslint --write

# If using Prettier as well
npx @biomejs/biome migrate prettier --write

# Remove old tooling after migration
npm uninstall eslint prettier \
  @typescript-eslint/eslint-plugin \
  @typescript-eslint/parser \
  eslint-config-next \
  eslint-plugin-react \
  eslint-plugin-react-hooks \
  eslint-config-prettier \
  prettier-plugin-tailwindcss

# Remove old config files
rm -f .eslintrc.js .eslintrc.json .eslintrc.cjs \
      .prettierrc .prettierrc.json .prettierrc.js \
      .eslintignore .prettierignore

# Run Biome to verify migration
npx @biomejs/biome check .

VS Code Settings

// .vscode/settings.json — use Biome as default formatter
{
  "editor.defaultFormatter": "biomejs.biome",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.biome": "explicit",
    "source.organizeImports.biome": "explicit"
  },
  "[javascript]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[typescript]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[json]": {
    "editor.defaultFormatter": "biomejs.biome"
  }
}

For the ESLint + Prettier combination when Biome’s rule coverage is insufficient — particularly for framework-specific ESLint plugins (eslint-plugin-tanstack-query, eslint-plugin-storybook) that have no Biome equivalent yet, see the ESLint configuration guide for flat config setup. For the oxlint Rust linter alternative to Biome that focuses purely on linting speed without formatting (pairs with Prettier) and is compatible with ESLint rules, the tooling comparison covers performance benchmarks. The Claude Skills 360 bundle includes Biome skill sets covering configuration, CI setup, and ESLint migration. Start with the free tier to try Biome configuration generation.

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free