Claude Skill

shared-tooling-biome

Biome v2 unified linter, formatter, and import organizer — single Rust-powered tool replacing ESLint + Prettier with 97% Prettier compatibility and 20x faster performance

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download agents-inc-skills-dist_plugins_shared-tooling-biome_skills_shared-tooling-biome-3a51ef5.zip · 24 KB
Part of agents-inc/skills — 130 skills

Install

skills CLI npx skills add https://github.com/agents-inc/skills/tree/main/dist/plugins/shared-tooling-biome/skills/shared-tooling-biome
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install agents-inc-skills@llmmart
Git git clone https://github.com/agents-inc/skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole agents-inc/skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Biome

Quick Guide: Biome is a unified linter, formatter, and import organizer for JavaScript, TypeScript, JSX, TSX, JSON, CSS, and GraphQL. Single Rust binary replaces ESLint + Prettier with 97% Prettier compatibility. Use biome.json for all configuration. Run biome check --write to lint, format, and organize imports in one pass. Use biome ci in pipelines.

Current stable version: Biome v2.4.x (March 2026). Biome v2 introduced type-aware linting, nested configs, and a revamped import organizer.


<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST use biome.json or biome.jsonc for ALL configuration — Biome does not use JavaScript config files)

(You MUST pin Biome to an exact version with --save-exact — Biome formatting can change between versions)

(You MUST use biome ci in CI pipelines, NOT biome check — ci is read-only with no --write flag)

(You MUST use biome check --write for local development — runs linter, formatter, and import organizer in one pass)

(You MUST include $schema in biome.json for editor autocompletion and validation)

</critical_requirements>


Auto-detection: Biome, biome.json, biome.jsonc, @biomejs/biome, biome check, biome lint, biome format, biome ci, biome-ignore, organizeImports, biome migrate

When to use:

  • Setting up a unified linter + formatter for JavaScript/TypeScript projects
  • Replacing ESLint + Prettier with a single, faster tool
  • Greenfield projects wanting zero-config or minimal-config setup
  • Large codebases where linting/formatting speed matters
  • Configuring import organizing with custom group ordering
  • Migrating from ESLint and/or Prettier to Biome
  • Setting up CI pipelines with biome ci
  • Configuring pre-commit hooks with Biome's --staged flag

When NOT to use:

  • Projects requiring ESLint plugins with no Biome equivalent (e.g., custom framework-specific plugins)
  • Projects heavily invested in custom ESLint rules that cannot be replicated
  • Projects needing Markdown, YAML, or TOML formatting (Biome does not support these yet)
  • Runtime code (this is build-time tooling only)
  • Git hooks framework setup (Husky/Lefthook configuration is a separate concern)
  • TypeScript compiler configuration (tsconfig.json is a separate concern)

Key patterns covered:

  • biome.json configuration with formatter, linter, and assist settings
  • Linter rule groups (recommended, all, nursery) and severity levels
  • Formatter configuration (indent style, line width, quotes, semicolons)
  • Import organizer with custom group ordering
  • CLI commands: check, format, lint, ci, migrate
  • Migration from ESLint + Prettier
  • Git hooks integration (Husky, Lefthook, --staged flag)
  • CI integration with GitHub Actions and GitLab CI
  • Editor integration (VS Code, JetBrains)
  • Suppression comments (biome-ignore, biome-ignore-all, range suppressions)
  • Nested configuration for monorepos
  • Overrides for file-specific settings

Examples

Other resources:





<decision_framework>

Decision Framework

Biome vs ESLint + Prettier

Need linting and formatting?
|-- Greenfield project?
|   |-- Want simplest possible setup? -> Biome (one tool, one config)
|   |-- Need niche ESLint plugins? -> ESLint + Prettier
|   +-- Speed is important? -> Biome (20x faster)
|-- Existing ESLint + Prettier project?
|   |-- Happy with current setup? -> Stay with ESLint + Prettier
|   |-- Config complexity is a pain? -> Migrate to Biome
|   |-- Need ESLint plugins without Biome equivalents? -> Stay
|   +-- Want faster CI/pre-commit hooks? -> Biome (or hybrid)
+-- Monorepo?
    |-- Need per-package lint configs? -> Biome v2 nested configs or ESLint 10
    +-- Speed bottleneck in CI? -> Biome

Configuration Complexity

How to configure Biome?
|-- Just starting out? -> Run `biome init`, use defaults with recommended: true
|-- Migrating from ESLint? -> Run `biome migrate eslint --write`
|-- Migrating from Prettier? -> Run `biome migrate prettier --write`
|-- Need per-file rules?
|   |-- Different rules for test files? -> Use `overrides` in biome.json
|   +-- Different rules per package? -> Use nested biome.json with "root": false
+-- Need custom import ordering? -> Configure organizeImports.options.groups

Full migration decision tree: See examples/migration.md.

</decision_framework>



<red_flags>

RED FLAGS

High Priority Issues:

  • Using biome check in CI instead of biome ci (check allows --write which is dangerous in pipelines; ci is read-only)
  • Not pinning Biome version with --save-exact (formatting can change between minor versions, causing diff noise)
  • Missing $schema in biome.json (loses editor autocompletion, validation, and discoverability)
  • Using JavaScript config files instead of biome.json (Biome only supports JSON/JSONC configuration)
  • Running biome format and biome lint separately when biome check does both (wastes time, parses files twice)

Medium Priority Issues:

  • Forgetting to set indentStyle: "space" when migrating from Prettier (Biome defaults to tabs)
  • Not enabling VCS integration (without it, Biome may process node_modules and dist)
  • Using --unsafe without reviewing changes (unsafe fixes can alter program behavior)
  • Not including --no-errors-on-unmatched in git hooks (causes failures when no matching files are staged)
  • Enabling all nursery rules (they are experimental and may have bugs or performance issues)

Common Mistakes:

  • Using "root": true in a nested config (this is the default; use "root": false for child configs)
  • Expecting Markdown/YAML formatting support (Biome does not support these languages yet)
  • Not running biome migrate --write when upgrading major versions (config schema changes between v1 and v2)
  • Suppression comments without explanations (biome-ignore lint: requires text after the colon)

Gotchas & Edge Cases:

  • Biome defaults to tabs, not spaces — always set indentStyle explicitly when migrating from Prettier
  • CSS and GraphQL formatting is disabled by default — must opt in with "formatter": { "enabled": true }
  • biome-ignore-all must be at the top of the file — placing it mid-file triggers an unused suppression warning
  • Import organizer is part of assist, not linter — configure under assist.actions.source.organizeImports
  • The --staged flag makes lint-staged unnecessary for Biome-only setups (since Biome v1.7.0+)
  • Type-aware linting (project/types domains) triggers file scanning which can slow down first runs on large projects
  • biome migrate eslint --write does not migrate inspired rules by default — use --include-inspired to include them
  • Range suppressions (biome-ignore-start/biome-ignore-end) must have matching rule specifiers
  • Biome treats all JS/TS/JSX/TSX under the javascript config key — there is no separate typescript section
  • Configuration files named .biome.json (with leading dot) are also discovered (v2.4+)

</red_flags>


<critical_reminders>

CRITICAL REMINDERS

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST use biome.json or biome.jsonc for ALL configuration — Biome does not use JavaScript config files)

(You MUST pin Biome to an exact version with --save-exact — Biome formatting can change between versions)

(You MUST use biome ci in CI pipelines, NOT biome check — ci is read-only with no --write flag)

(You MUST use biome check --write for local development — runs linter, formatter, and import organizer in one pass)

(You MUST include $schema in biome.json for editor autocompletion and validation)

Failure to follow these rules will cause inconsistent formatting, broken CI pipelines, and missed lint errors.

</critical_reminders>

Files (skills)
  • examples
    • biome.md 15.9 KB
      # Biome Configuration Examples
      
      > Practical examples for Biome configuration, migration, CI integration, and custom rules. See [SKILL.md](../SKILL.md) for core patterns and [reference.md](../reference.md) for CLI quick reference.
      
      ---
      
      ## Standard Project Setup
      
      ### Step-by-Step Initialization
      
      ```bash
      # 1. Install Biome (always pin exact version)
      npm install --save-dev --save-exact @biomejs/biome
      
      # 2. Create default biome.json
      npx @biomejs/biome init
      
      # 3. Add scripts to package.json
      ```
      
      ```jsonc
      // package.json
      {
        "scripts": {
          "check": "biome check .",
          "check:fix": "biome check --write .",
          "format": "biome format --write .",
          "lint": "biome lint .",
          "lint:fix": "biome lint --write .",
          "ci": "biome ci .",
        },
        "devDependencies": {
          "@biomejs/biome": "2.4.7",
        },
      }
      ```
      
      ### Production-Ready biome.json
      
      ```jsonc
      // biome.json
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "vcs": {
          "enabled": true,
          "clientKind": "git",
          "useIgnoreFile": true,
          "defaultBranch": "main",
        },
        "files": {
          "ignoreUnknown": true,
          "includes": ["**"],
        },
        "formatter": {
          "enabled": true,
          "indentStyle": "space",
          "indentWidth": 2,
          "lineWidth": 100,
          "lineEnding": "lf",
        },
        "linter": {
          "enabled": true,
          "rules": {
            "recommended": true,
            "correctness": {
              "noUnusedImports": "error",
              "noUnusedVariables": "warn",
            },
            "style": {
              "noDefaultExport": "warn",
              "useImportType": "error",
            },
            "suspicious": {
              "noExplicitAny": "warn",
            },
          },
        },
        "assist": {
          "enabled": true,
          "actions": {
            "source": {
              "organizeImports": "on",
            },
          },
        },
        "javascript": {
          "formatter": {
            "quoteStyle": "double",
            "semicolons": "always",
            "trailingCommas": "all",
            "arrowParentheses": "always",
            "bracketSameLine": false,
          },
        },
        "json": {
          "formatter": {
            "trailingCommas": "none",
          },
        },
        "css": {
          "formatter": {
            "enabled": true,
          },
        },
        "overrides": [
          {
            "includes": ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts"],
            "linter": {
              "rules": {
                "suspicious": {
                  "noExplicitAny": "off",
                },
              },
            },
          },
        ],
      }
      ```
      
      **Why good:** `$schema` enables editor autocompletion, VCS integration skips `.gitignore`d files, explicit formatter settings prevent tab/space surprises, `noUnusedImports` catches dead imports, `useImportType` enforces `import type`, `noDefaultExport` encourages named exports, test file overrides relax strict rules where needed, CSS formatting explicitly enabled
      
      ---
      
      ## Migration from ESLint + Prettier
      
      ### Automated Migration
      
      ```bash
      # Step 1: Migrate Prettier settings (indent, quotes, line width)
      npx @biomejs/biome migrate prettier --write
      
      # Step 2: Migrate ESLint rules (maps to Biome equivalents)
      npx @biomejs/biome migrate eslint --write
      
      # Step 3: Include rules that are "inspired by" ESLint (not exact matches)
      npx @biomejs/biome migrate eslint --write --include-inspired
      
      # Step 4: Enable VCS integration (ESLint respects .gitignore by default)
      # Add to biome.json manually:
      # "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true }
      
      # Step 5: Verify migration
      npx @biomejs/biome check .
      
      # Step 6: Remove old tooling
      npm uninstall eslint prettier eslint-config-prettier eslint-plugin-only-warn \
        @eslint/js typescript-eslint eslint-plugin-react eslint-plugin-jsx-a11y
      
      # Step 7: Remove old config files
      rm -f .eslintrc* eslint.config.* .prettierrc* prettier.config.* .eslintignore .prettierignore
      ```
      
      ### Manual Migration Checklist
      
      | ESLint + Prettier                            | Biome Equivalent                              |
      | -------------------------------------------- | --------------------------------------------- |
      | `.eslintrc.json` / `eslint.config.ts`        | `biome.json`                                  |
      | `.prettierrc` / `prettier.config.mjs`        | `biome.json` (formatter section)              |
      | `.eslintignore`                              | `biome.json` files.includes with `!` patterns |
      | `.prettierignore`                            | `biome.json` files.includes with `!` patterns |
      | `eslint-config-prettier`                     | Not needed (no formatter/linter conflicts)    |
      | `eslint-plugin-only-warn`                    | Set rule severity to `"warn"`                 |
      | `eslint-plugin-import`                       | `assist.actions.source.organizeImports`       |
      | `@typescript-eslint/parser`                  | Built-in TypeScript support                   |
      | `@typescript-eslint/consistent-type-imports` | `style/useImportType`                         |
      | `@typescript-eslint/no-unused-vars`          | `correctness/noUnusedVariables`               |
      | `import/no-default-export`                   | `style/noDefaultExport`                       |
      | `no-console`                                 | `nursery/noConsole`                           |
      
      ### Removing Unnecessary Packages
      
      After migration, these packages are no longer needed:
      
      ```bash
      # Core tools (replaced by Biome)
      npm uninstall eslint prettier
      
      # ESLint plugins (handled by Biome rules)
      npm uninstall @eslint/js typescript-eslint eslint-config-prettier
      npm uninstall eslint-plugin-only-warn eslint-plugin-react
      npm uninstall eslint-plugin-jsx-a11y eslint-plugin-unicorn
      npm uninstall eslint-plugin-import eslint-plugin-simple-import-sort
      
      # Prettier plugins
      npm uninstall @prettier/sync prettier-plugin-tailwindcss
      ```
      
      ---
      
      ## Custom Import Ordering
      
      ### React Project with Company Packages
      
      ```jsonc
      {
        "assist": {
          "actions": {
            "source": {
              "organizeImports": {
                "level": "on",
                "options": {
                  "groups": [
                    ":NODE:",
                    ":PACKAGE:",
                    ":BLANK_LINE:",
                    ["@company/**"],
                    ":BLANK_LINE:",
                    ":ALIAS:",
                    ["../**", "./**"],
                  ],
                },
              },
            },
          },
        },
      }
      ```
      
      **Result:**
      
      ```typescript
      import { readFileSync } from "node:fs";
      
      import { z } from "zod";
      import { useQuery } from "@tanstack/react-query";
      
      import { apiClient } from "@company/api-client";
      import { Button } from "@company/ui";
      
      import { useAuth } from "@/hooks/use-auth";
      
      import { formatDate } from "../utils/date";
      import { UserCard } from "./user-card";
      ```
      
      ### Separating Type Imports
      
      ```jsonc
      {
        "assist": {
          "actions": {
            "source": {
              "organizeImports": {
                "level": "on",
                "options": {
                  "groups": [{ "type": false }, ":BLANK_LINE:", { "type": true }],
                },
              },
            },
          },
        },
      }
      ```
      
      **Result:**
      
      ```typescript
      import { z } from "zod";
      import { useQuery } from "@tanstack/react-query";
      import { Button } from "./button";
      
      import type { User } from "../types/user";
      import type { ApiResponse } from "@company/api-client";
      ```
      
      ---
      
      ## Monorepo Nested Configuration
      
      ### Root Configuration
      
      ```jsonc
      // biome.json (project root)
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "vcs": {
          "enabled": true,
          "clientKind": "git",
          "useIgnoreFile": true,
        },
        "formatter": {
          "indentStyle": "space",
          "indentWidth": 2,
          "lineWidth": 100,
          "lineEnding": "lf",
        },
        "linter": {
          "rules": {
            "recommended": true,
            "style": {
              "noDefaultExport": "warn",
              "useImportType": "error",
            },
          },
        },
        "assist": {
          "enabled": true,
          "actions": {
            "source": {
              "organizeImports": "on",
            },
          },
        },
        "javascript": {
          "formatter": {
            "quoteStyle": "double",
            "semicolons": "always",
            "trailingCommas": "all",
          },
        },
      }
      ```
      
      ### Next.js App Override
      
      ```jsonc
      // apps/web/biome.json
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "extends": "//",
        "linter": {
          "rules": {
            "style": {
              // Next.js requires default exports for pages and layouts
              "noDefaultExport": "off",
            },
          },
          "domains": {
            "react": "recommended",
          },
        },
        "overrides": [
          {
            "includes": [
              "**/app/**/page.tsx",
              "**/app/**/layout.tsx",
              "**/app/**/loading.tsx",
            ],
            "linter": {
              "rules": {
                "style": {
                  "noDefaultExport": "off",
                },
              },
            },
          },
        ],
      }
      ```
      
      ### Legacy Package Override
      
      ```jsonc
      // packages/legacy-lib/biome.json
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "root": false,
        "linter": {
          "rules": {
            "suspicious": {
              "noExplicitAny": "off",
            },
            "correctness": {
              "noUnusedVariables": "off",
            },
          },
        },
      }
      ```
      
      **Why good:** Root config establishes team-wide standards, `"extends": "//"` shorthand inherits root config, Next.js app relaxes default export rule where framework requires it, legacy package can disable strict rules while the rest of the monorepo stays strict
      
      ---
      
      ## CI Integration Examples
      
      ### GitHub Actions (Minimal)
      
      ```yaml
      # .github/workflows/lint.yml
      name: Lint & Format
      on: [push, pull_request]
      
      jobs:
        biome:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v4
            - uses: biomejs/setup-biome@v2
            - run: biome ci .
      ```
      
      ### GitHub Actions (Full Pipeline)
      
      ```yaml
      # .github/workflows/quality.yml
      name: Code Quality
      on:
        push:
          branches: [main]
        pull_request:
      
      jobs:
        biome:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v4
      
            # Option A: Use setup-biome (no Node.js needed)
            - uses: biomejs/setup-biome@v2
              with:
                version: latest
      
            # Run Biome CI with strict mode
            - run: biome ci --error-on-warnings --max-diagnostics=100 .
      
        # If using Biome with other Node.js tools
        biome-with-node:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v4
            - uses: actions/setup-node@v4
              with:
                node-version: 22
                cache: npm
            - run: npm ci
            - run: npx biome ci .
      ```
      
      ### GitHub Actions (Changed Files Only)
      
      ```yaml
      # .github/workflows/lint-changed.yml
      name: Lint Changed Files
      on: pull_request
      
      jobs:
        biome:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v4
              with:
                fetch-depth: 0
            - uses: biomejs/setup-biome@v2
            - run: biome ci --changed --since=origin/main .
      ```
      
      ### GitLab CI
      
      ```yaml
      # .gitlab-ci.yml
      biome:
        image:
          name: ghcr.io/biomejs/biome:latest
          entrypoint: [""]
        stage: lint
        script:
          - biome ci --reporter=gitlab --colors=off > /tmp/code-quality.json
        artifacts:
          reports:
            codequality:
              - code-quality.json
        rules:
          - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      ```
      
      ---
      
      ## Git Hooks Configuration
      
      ### Husky with --staged (Simplest)
      
      ```bash
      # Install and configure Husky
      npm install --save-dev husky
      npx husky init
      ```
      
      ```bash
      # .husky/pre-commit
      npx biome check --write --staged --files-ignore-unknown=true --no-errors-on-unmatched
      ```
      
      **Why good:** The `--staged` flag (Biome v1.7.0+) eliminates the need for lint-staged entirely — Biome handles staged file filtering natively
      
      ### Lefthook
      
      ```yaml
      # lefthook.yml
      pre-commit:
        commands:
          biome-check:
            glob: "*.{js,ts,cjs,mjs,jsx,tsx,json,jsonc,css}"
            run: >
              npx @biomejs/biome check --write
              --no-errors-on-unmatched
              --files-ignore-unknown=true
              --colors=off
              {staged_files}
            stage_fixed: true
      ```
      
      ### pre-commit Framework
      
      ```yaml
      # .pre-commit-config.yaml
      repos:
        - repo: https://github.com/biomejs/pre-commit
          rev: "v2.0.6"
          hooks:
            - id: biome-check
              additional_dependencies: ["@biomejs/biome@2.4.7"]
      ```
      
      ---
      
      ## Framework-Specific Configurations
      
      ### React/Next.js
      
      ```jsonc
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "linter": {
          "rules": {
            "recommended": true,
            "correctness": {
              "noUnusedImports": "error",
              "useExhaustiveDependencies": "warn",
            },
            "style": {
              "useImportType": "error",
            },
          },
          "domains": {
            "react": "recommended",
          },
        },
        "javascript": {
          "jsxRuntime": "transparent",
        },
      }
      ```
      
      ### Node.js/Server
      
      ```jsonc
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "linter": {
          "rules": {
            "recommended": true,
            "correctness": {
              "noUnusedImports": "error",
              "noUnusedVariables": "warn",
            },
            "style": {
              "noDefaultExport": "error",
              "useImportType": "error",
              "useNodejsImportProtocol": "error",
            },
            "suspicious": {
              "noExplicitAny": "error",
            },
          },
        },
      }
      ```
      
      ### Project with CSS Support
      
      ```jsonc
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "css": {
          "formatter": {
            "enabled": true,
            "indentStyle": "space",
            "indentWidth": 2,
          },
          "linter": {
            "enabled": true,
          },
          "parser": {
            "cssModules": true,
          },
        },
      }
      ```
      
      ---
      
      ## Suppression Examples
      
      ### Inline Suppressions
      
      ```typescript
      // Suppress a specific rule
      // biome-ignore lint/suspicious/noDebugger: needed during local development
      debugger;
      
      // Suppress formatter for a complex expression
      // biome-ignore format: manual alignment is clearer here
      const matrix = [
        [1, 0, 0],
        [0, 1, 0],
        [0, 0, 1],
      ];
      
      // Suppress an entire group
      // biome-ignore lint/style: legacy code, will refactor later
      var x = 1;
      ```
      
      ### File-Level Suppressions
      
      ```typescript
      // biome-ignore-all lint/style/noDefaultExport: Next.js page requires default export
      // biome-ignore-all lint/correctness/noUnusedVariables: template file with example vars
      
      export default function Page() {
        const example = "placeholder";
        return <div>{example}</div>;
      }
      ```
      
      ### Range Suppressions
      
      ```typescript
      // biome-ignore-start lint/suspicious/noDoubleEquals: legacy null checks
      function processLegacyData(input: unknown) {
        if (input == null) return;
        if (input == undefined) return;
      }
      // biome-ignore-end lint/suspicious/noDoubleEquals: legacy null checks
      
      // Modern code below uses strict equality
      function processData(input: unknown) {
        if (input === null || input === undefined) return;
      }
      ```
      
      ---
      
      ## Overrides for Mixed Projects
      
      ### Test Files, Config Files, and Generated Code
      
      ```jsonc
      {
        "linter": {
          "rules": {
            "recommended": true,
            "style": {
              "noDefaultExport": "warn",
              "useImportType": "error",
            },
          },
        },
        "overrides": [
          {
            // Test files: relax strictness
            "includes": [
              "**/*.test.ts",
              "**/*.test.tsx",
              "**/*.spec.ts",
              "**/__tests__/**",
            ],
            "linter": {
              "rules": {
                "suspicious": {
                  "noExplicitAny": "off",
                },
                "style": {
                  "noDefaultExport": "off",
                },
              },
              "domains": {
                "test": "recommended",
              },
            },
          },
          {
            // Config files: allow default exports (Vite, etc.)
            "includes": ["*.config.ts", "*.config.mjs", "*.config.js"],
            "linter": {
              "rules": {
                "style": {
                  "noDefaultExport": "off",
                },
              },
            },
          },
          {
            // Generated files: disable linting and formatting
            "includes": ["**/generated/**", "**/*.generated.ts"],
            "linter": {
              "enabled": false,
            },
            "formatter": {
              "enabled": false,
            },
          },
        ],
      }
      ```
      
      **Why good:** Production code stays strict, test files get appropriate relaxations, config files allow framework-required default exports, generated code is completely excluded from processing
      
      ---
      
      ## See Also
      
      - [reference.md](../reference.md) for CLI quick reference and configuration options
      - [SKILL.md](../SKILL.md) for core patterns and philosophy
      
      **Official Documentation:**
      
      - [Biome Getting Started](https://biomejs.dev/guides/getting-started/)
      - [Biome Configuration](https://biomejs.dev/guides/configure-biome/)
      - [Biome Migration Guide](https://biomejs.dev/guides/migrate-eslint-prettier/)
      - [Biome Git Hooks](https://biomejs.dev/recipes/git-hooks/)
      - [Biome CI Integration](https://biomejs.dev/recipes/continuous-integration/)
      
    • ci.md 5.2 KB
      # Biome -- CI & Git Hooks Examples
      
      > CI pipeline integration, pre-commit hooks, and staged file processing. Reference from [SKILL.md](../SKILL.md).
      
      **Related examples:**
      
      - [core.md](core.md) -- Installation, biome.json config, editor integration
      - [linting.md](linting.md) -- Lint rules, domains, suppressions, overrides
      - [formatting.md](formatting.md) -- Formatter config, Prettier compatibility
      - [migration.md](migration.md) -- Migrating from ESLint + Prettier
      
      ---
      
      ## GitHub Actions (Minimal)
      
      ```yaml
      # .github/workflows/lint.yml
      name: Lint & Format
      on: [push, pull_request]
      
      jobs:
        biome:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v4
            - uses: biomejs/setup-biome@v2
            - run: biome ci .
      ```
      
      **Key:** The `biomejs/setup-biome` action installs the Biome binary directly -- no Node.js or npm required.
      
      ---
      
      ## GitHub Actions (Full Pipeline)
      
      ```yaml
      # .github/workflows/quality.yml
      name: Code Quality
      on:
        push:
          branches: [main]
        pull_request:
      
      jobs:
        biome:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v4
      
            # Option A: Use setup-biome (no Node.js needed)
            - uses: biomejs/setup-biome@v2
              with:
                version: latest
      
            # Run Biome CI with strict mode
            - run: biome ci --error-on-warnings --max-diagnostics=100 .
      
        # If using Biome with other Node.js tools
        biome-with-node:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v4
            - uses: actions/setup-node@v4
              with:
                node-version: 22
                cache: npm
            - run: npm ci
            - run: npx biome ci .
      ```
      
      ---
      
      ## GitHub Actions (Changed Files Only)
      
      ```yaml
      # .github/workflows/lint-changed.yml
      name: Lint Changed Files
      on: pull_request
      
      jobs:
        biome:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v4
              with:
                fetch-depth: 0
            - uses: biomejs/setup-biome@v2
            - run: biome ci --changed --since=origin/main .
      ```
      
      ---
      
      ## GitLab CI
      
      ```yaml
      # .gitlab-ci.yml
      biome:
        image:
          name: ghcr.io/biomejs/biome:latest
          entrypoint: [""]
        stage: lint
        script:
          - biome ci --reporter=gitlab --colors=off > /tmp/code-quality.json
        artifacts:
          reports:
            codequality:
              - code-quality.json
        rules:
          - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      ```
      
      ---
      
      ## CLI Commands for CI vs Local
      
      ```bash
      # Run everything: lint + format + organize imports (read-only)
      npx biome check .
      
      # Run everything with auto-fix
      npx biome check --write .
      
      # Format only
      npx biome format --write .
      
      # Lint only
      npx biome lint --write .
      
      # CI mode (read-only, optimized for pipelines)
      npx biome ci .
      ```
      
      ### Filtering and Targeting
      
      ```bash
      # Run only specific rule groups
      npx biome lint --only=correctness .
      
      # Skip specific rules
      npx biome lint --skip=style/useNamingConvention .
      
      # Check only staged files (pre-commit hooks)
      npx biome check --staged --write .
      
      # Check only changed files (compared to main branch)
      npx biome check --changed --since=main .
      
      # Apply unsafe fixes (requires review)
      npx biome check --write --unsafe .
      ```
      
      ### Output and Reporting
      
      ```bash
      # Verbose output
      npx biome check --verbose .
      
      # JSON reporter
      npx biome ci --reporter=json .
      
      # GitHub annotations (auto-detected in GitHub Actions)
      npx biome ci --reporter=github .
      
      # GitLab code quality report
      npx biome ci --reporter=gitlab --colors=off > code-quality.json
      
      # Error on warnings (strict mode)
      npx biome ci --error-on-warnings .
      
      # Limit diagnostics output
      npx biome check --max-diagnostics=50 .
      ```
      
      **Why good:** `check --write` handles everything in one command, `ci` is purpose-built for pipelines (no `--write` flag, better runner integration), `--staged` eliminates the need for lint-staged, `--changed` enables incremental CI checks
      
      ---
      
      ## Git Hooks
      
      ### Husky with --staged (Simplest)
      
      ```bash
      # Install and configure Husky
      npm install --save-dev husky
      npx husky init
      ```
      
      ```bash
      # .husky/pre-commit
      npx biome check --write --staged --files-ignore-unknown=true --no-errors-on-unmatched
      ```
      
      **Why good:** The `--staged` flag (Biome v1.7.0+) eliminates the need for lint-staged entirely -- Biome handles staged file filtering natively
      
      ### Husky + lint-staged
      
      If using lint-staged for multiple tools:
      
      ```jsonc
      // package.json
      {
        "lint-staged": {
          "*.{js,ts,jsx,tsx,json,jsonc,css}": [
            "biome check --write --no-errors-on-unmatched",
          ],
        },
      }
      ```
      
      ### Lefthook
      
      ```yaml
      # lefthook.yml
      pre-commit:
        commands:
          biome-check:
            glob: "*.{js,ts,cjs,mjs,jsx,tsx,json,jsonc,css}"
            run: >
              npx @biomejs/biome check --write
              --no-errors-on-unmatched
              --files-ignore-unknown=true
              --colors=off
              {staged_files}
            stage_fixed: true
      ```
      
      ### pre-commit Framework
      
      ```yaml
      # .pre-commit-config.yaml
      repos:
        - repo: https://github.com/biomejs/pre-commit
          rev: "v2.0.6"
          hooks:
            - id: biome-check
              additional_dependencies: ["@biomejs/biome@2.4.7"]
      ```
      
      ---
      
      ## See Also
      
      - [SKILL.md](../SKILL.md) for core patterns and philosophy
      - [reference.md](../reference.md) for complete CLI flags reference
      
      **Official Documentation:**
      
      - [Biome CI Integration](https://biomejs.dev/recipes/continuous-integration/)
      - [Biome Git Hooks](https://biomejs.dev/recipes/git-hooks/)
      - [Biome CLI Reference](https://biomejs.dev/reference/cli/)
      
    • core.md 7.7 KB
      # Biome -- Setup & Configuration Examples
      
      > Installation, biome.json configuration, editor integration, and package.json scripts. Reference from [SKILL.md](../SKILL.md).
      
      **Related examples:**
      
      - [linting.md](linting.md) -- Lint rules, domains, suppressions, overrides
      - [formatting.md](formatting.md) -- Formatter config, Prettier compatibility
      - [ci.md](ci.md) -- CI pipelines, git hooks, staged files
      - [migration.md](migration.md) -- Migrating from ESLint + Prettier
      
      ---
      
      ## Step-by-Step Initialization
      
      ```bash
      # 1. Install Biome (always pin exact version)
      npm install --save-dev --save-exact @biomejs/biome
      
      # 2. Create default biome.json
      npx @biomejs/biome init
      
      # 3. Add scripts to package.json
      ```
      
      ```jsonc
      // package.json
      {
        "scripts": {
          "check": "biome check .",
          "check:fix": "biome check --write .",
          "format": "biome format --write .",
          "lint": "biome lint .",
          "lint:fix": "biome lint --write .",
          "ci": "biome ci .",
        },
        "devDependencies": {
          "@biomejs/biome": "2.4.7",
        },
      }
      ```
      
      ---
      
      ## Production-Ready biome.json
      
      ```jsonc
      // biome.json
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "vcs": {
          "enabled": true,
          "clientKind": "git",
          "useIgnoreFile": true,
          "defaultBranch": "main",
        },
        "files": {
          "ignoreUnknown": true,
          "includes": ["**"],
        },
        "formatter": {
          "enabled": true,
          "indentStyle": "space",
          "indentWidth": 2,
          "lineWidth": 100,
          "lineEnding": "lf",
        },
        "linter": {
          "enabled": true,
          "rules": {
            "recommended": true,
            "correctness": {
              "noUnusedImports": "error",
              "noUnusedVariables": "warn",
            },
            "style": {
              "noDefaultExport": "warn",
              "useImportType": "error",
            },
            "suspicious": {
              "noExplicitAny": "warn",
            },
          },
        },
        "assist": {
          "enabled": true,
          "actions": {
            "source": {
              "organizeImports": "on",
            },
          },
        },
        "javascript": {
          "formatter": {
            "quoteStyle": "double",
            "semicolons": "always",
            "trailingCommas": "all",
            "arrowParentheses": "always",
            "bracketSameLine": false,
          },
        },
        "json": {
          "formatter": {
            "trailingCommas": "none",
          },
        },
        "css": {
          "formatter": {
            "enabled": true,
          },
        },
        "overrides": [
          {
            "includes": ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts"],
            "linter": {
              "rules": {
                "suspicious": {
                  "noExplicitAny": "off",
                },
              },
            },
          },
        ],
      }
      ```
      
      **Why good:** `$schema` enables editor autocompletion, VCS integration skips `.gitignore`d files, explicit formatter settings prevent tab/space surprises, `noUnusedImports` catches dead imports, `useImportType` enforces `import type`, `noDefaultExport` encourages named exports, test file overrides relax strict rules where needed, CSS formatting explicitly enabled
      
      ---
      
      ## VS Code Integration
      
      Install the [Biome extension](https://marketplace.visualstudio.com/items?itemName=biomejs.biome) from the VS Code Marketplace.
      
      ```jsonc
      // .vscode/settings.json
      {
        // Set Biome as default formatter
        "editor.defaultFormatter": "biomejs.biome",
        // Format on save
        "editor.formatOnSave": true,
        // Organize imports on save
        "editor.codeActionsOnSave": {
          "source.organizeImports.biome": "explicit",
        },
        // Language-specific overrides (if needed)
        "[javascript]": {
          "editor.defaultFormatter": "biomejs.biome",
        },
        "[typescript]": {
          "editor.defaultFormatter": "biomejs.biome",
        },
        "[json]": {
          "editor.defaultFormatter": "biomejs.biome",
        },
      }
      ```
      
      **VS Code Extension v3 features:**
      
      - Multi-root workspace support (each folder runs its own Biome instance)
      - Single-file mode for files outside projects
      - Automatic `biome.json` discovery
      
      ---
      
      ## JetBrains (IntelliJ, WebStorm)
      
      Install the [Biome plugin](https://plugins.jetbrains.com/plugin/22761-biome) from the JetBrains Marketplace.
      
      The plugin auto-discovers Biome from `node_modules/.bin/biome`. Add Biome as a project dependency to ensure the plugin and CLI use the same version.
      
      ---
      
      ## Framework-Specific Configurations
      
      ### React / Next.js
      
      ```jsonc
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "linter": {
          "rules": {
            "recommended": true,
            "correctness": {
              "noUnusedImports": "error",
              "useExhaustiveDependencies": "warn",
            },
            "style": {
              "useImportType": "error",
            },
          },
          "domains": {
            "react": "recommended",
          },
        },
        "javascript": {
          "jsxRuntime": "transparent",
        },
      }
      ```
      
      ### Node.js / Server
      
      ```jsonc
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "linter": {
          "rules": {
            "recommended": true,
            "correctness": {
              "noUnusedImports": "error",
              "noUnusedVariables": "warn",
            },
            "style": {
              "noDefaultExport": "error",
              "useImportType": "error",
              "useNodejsImportProtocol": "error",
            },
            "suspicious": {
              "noExplicitAny": "error",
            },
          },
        },
      }
      ```
      
      ### CSS Support
      
      ```jsonc
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "css": {
          "formatter": {
            "enabled": true,
            "indentStyle": "space",
            "indentWidth": 2,
          },
          "linter": {
            "enabled": true,
          },
          "parser": {
            "cssModules": true,
          },
        },
      }
      ```
      
      ---
      
      ## Monorepo Nested Configuration
      
      ### Root Configuration
      
      ```jsonc
      // biome.json (project root)
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "vcs": {
          "enabled": true,
          "clientKind": "git",
          "useIgnoreFile": true,
        },
        "formatter": {
          "indentStyle": "space",
          "indentWidth": 2,
          "lineWidth": 100,
          "lineEnding": "lf",
        },
        "linter": {
          "rules": {
            "recommended": true,
            "style": {
              "noDefaultExport": "warn",
              "useImportType": "error",
            },
          },
        },
        "assist": {
          "enabled": true,
          "actions": {
            "source": {
              "organizeImports": "on",
            },
          },
        },
        "javascript": {
          "formatter": {
            "quoteStyle": "double",
            "semicolons": "always",
            "trailingCommas": "all",
          },
        },
      }
      ```
      
      ### Next.js App Override
      
      ```jsonc
      // apps/web/biome.json
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "extends": "//",
        "linter": {
          "rules": {
            "style": {
              // Next.js requires default exports for pages and layouts
              "noDefaultExport": "off",
            },
          },
          "domains": {
            "react": "recommended",
          },
        },
        "overrides": [
          {
            "includes": [
              "**/app/**/page.tsx",
              "**/app/**/layout.tsx",
              "**/app/**/loading.tsx",
            ],
            "linter": {
              "rules": {
                "style": {
                  "noDefaultExport": "off",
                },
              },
            },
          },
        ],
      }
      ```
      
      ### Legacy Package Override
      
      ```jsonc
      // packages/legacy-lib/biome.json
      {
        "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
        "root": false,
        "linter": {
          "rules": {
            "suspicious": {
              "noExplicitAny": "off",
            },
            "correctness": {
              "noUnusedVariables": "off",
            },
          },
        },
      }
      ```
      
      **Why good:** Root config establishes team-wide standards, `"extends": "//"` shorthand inherits root config, Next.js app relaxes default export rule where framework requires it, legacy package can disable strict rules while the rest of the monorepo stays strict
      
      ---
      
      ## See Also
      
      - [SKILL.md](../SKILL.md) for core patterns and philosophy
      - [reference.md](../reference.md) for CLI quick reference and configuration options
      
      **Official Documentation:**
      
      - [Biome Getting Started](https://biomejs.dev/guides/getting-started/)
      - [Biome Configuration](https://biomejs.dev/guides/configure-biome/)
      - [Biome VS Code Extension](https://biomejs.dev/reference/vscode/)
      
    • formatting.md 2.7 KB
      # Biome -- Formatting Examples
      
      > Formatter configuration, language-specific settings, and Prettier compatibility. Reference from [SKILL.md](../SKILL.md).
      
      **Related examples:**
      
      - [core.md](core.md) -- Installation, biome.json config, editor integration
      - [linting.md](linting.md) -- Lint rules, domains, suppressions, overrides
      - [ci.md](ci.md) -- CI pipelines, git hooks, staged files
      - [migration.md](migration.md) -- Migrating from ESLint + Prettier
      
      ---
      
      ## Global vs Language-Specific Settings
      
      ```jsonc
      {
        // Global formatter settings (all languages)
        "formatter": {
          "indentStyle": "space",
          "indentWidth": 2,
          "lineWidth": 100,
          "lineEnding": "lf",
          "bracketSpacing": true,
        },
        // JavaScript/TypeScript-specific overrides
        "javascript": {
          "formatter": {
            "quoteStyle": "double",
            "jsxQuoteStyle": "double",
            "semicolons": "always",
            "trailingCommas": "all",
            "arrowParentheses": "always",
            "bracketSameLine": false,
          },
        },
        // JSON-specific settings
        "json": {
          "formatter": {
            "trailingCommas": "none",
          },
        },
        // CSS formatting (disabled by default, opt-in)
        "css": {
          "formatter": {
            "enabled": true,
          },
        },
      }
      ```
      
      **Why good:** Global settings provide a baseline for all languages, language-specific settings override without repetition, CSS/GraphQL formatting explicitly opted into since they are disabled by default
      
      ---
      
      ## Key Differences from Prettier Defaults
      
      | Setting          | Biome Default | Prettier Default | Notes                  |
      | ---------------- | ------------- | ---------------- | ---------------------- |
      | `indentStyle`    | `"tab"`       | spaces           | Biome defaults to tabs |
      | `indentWidth`    | `2`           | `2`              | Same                   |
      | `lineWidth`      | `80`          | `80`             | Same                   |
      | `quoteStyle`     | `"double"`    | `"double"`       | Same                   |
      | `semicolons`     | `"always"`    | `true`           | Different naming       |
      | `trailingCommas` | `"all"`       | `"all"`          | Same (Prettier 3.0+)   |
      
      **Important:** When migrating from Prettier, explicitly set `indentStyle: "space"` if your project uses spaces -- Biome defaults to tabs.
      
      ---
      
      > For the Prettier-to-Biome option name mapping table, see [reference.md](../reference.md#biome-vs-prettier-option-name-mapping).
      
      ---
      
      ## See Also
      
      - [SKILL.md](../SKILL.md) for core patterns and philosophy
      - [reference.md](../reference.md) for CLI quick reference
      
      **Official Documentation:**
      
      - [Biome Configuration Reference](https://biomejs.dev/reference/configuration/)
      - [Biome Migration Guide](https://biomejs.dev/guides/migrate-eslint-prettier/)
      
    • linting.md 6.9 KB
      # Biome -- Linting Examples
      
      > Lint rules configuration, domains, suppression comments, and file-specific overrides. Reference from [SKILL.md](../SKILL.md).
      
      **Related examples:**
      
      - [core.md](core.md) -- Installation, biome.json config, editor integration
      - [formatting.md](formatting.md) -- Formatter config, Prettier compatibility
      - [ci.md](ci.md) -- CI pipelines, git hooks, staged files
      - [migration.md](migration.md) -- Migrating from ESLint + Prettier
      
      ---
      
      ## Rule Configuration
      
      ### Recommended Baseline with Customizations
      
      ```jsonc
      // biome.json
      {
        "linter": {
          "enabled": true,
          "rules": {
            "recommended": true,
            // Enable all style rules, then configure individual ones
            "style": {
              "all": true,
              "useNamingConvention": {
                "level": "warn",
                "options": {
                  "strictCase": false,
                },
              },
            },
            // Disable specific rules
            "complexity": {
              "noForEach": "off",
            },
            // Enable nursery rules explicitly
            "nursery": {
              "noConsole": "warn",
            },
          },
        },
      }
      ```
      
      **Why good:** `recommended: true` provides a strong baseline without per-rule config, group-level overrides (`"all": true`) enable entire categories, individual rules can be tuned with options, nursery rules opted into explicitly for experimental features
      
      ---
      
      ## Domains (Technology-Specific Rules)
      
      Biome v2 introduces domains that group rules by technology:
      
      ```jsonc
      {
        "linter": {
          "domains": {
            "react": "recommended",
            "test": "recommended",
            "solid": "off",
          },
        },
      }
      ```
      
      Domains auto-detect from `package.json` dependencies when not explicitly configured.
      
      | Domain    | Detected From               | Purpose                      |
      | --------- | --------------------------- | ---------------------------- |
      | `react`   | react in package.json       | React-specific rules         |
      | `solid`   | solid-js in package.json    | SolidJS-specific rules       |
      | `test`    | vitest/jest in package.json | Test-specific rules          |
      | `project` | Manual opt-in               | Cross-file analysis rules    |
      | `types`   | Manual opt-in               | Type inference rules (v2.4+) |
      
      ---
      
      ## Suppression Comments
      
      ### Inline Suppression (Next Line)
      
      ```typescript
      // Suppress a specific rule
      // biome-ignore lint/suspicious/noDebugger: needed during local development
      debugger;
      
      // Suppress formatter for a complex expression
      // biome-ignore format: manual alignment is clearer here
      const matrix = [
        [1, 0, 0],
        [0, 1, 0],
        [0, 0, 1],
      ];
      
      // Suppress an entire group
      // biome-ignore lint/style: legacy code, will refactor later
      var x = 1;
      ```
      
      ### File-Level Suppression (Top of File)
      
      ```typescript
      // biome-ignore-all lint/style/noDefaultExport: Next.js page requires default export
      // biome-ignore-all lint/correctness/noUnusedVariables: template file with example vars
      
      export default function Page() {
        const example = "placeholder";
        return <div>{example}</div>;
      }
      ```
      
      **Important:** `biome-ignore-all` must be placed at the top of the file. Placing it mid-file triggers an unused suppression warning.
      
      ### Range Suppression
      
      ```typescript
      // biome-ignore-start lint/suspicious/noDoubleEquals: legacy null checks
      function processLegacyData(input: unknown) {
        if (input == null) return;
        if (input == undefined) return;
      }
      // biome-ignore-end lint/suspicious/noDoubleEquals: legacy null checks
      
      // Modern code below uses strict equality
      function processData(input: unknown) {
        if (input === null || input === undefined) return;
      }
      ```
      
      Suppressions can target a category (`lint`), group (`lint/suspicious`), or individual rule (`lint/suspicious/noDebugger`). See [reference.md](../reference.md#suppression-comment-syntax) for the full specifier table.
      
      **Important:** Explanations are mandatory. `// biome-ignore lint:` without a reason after the colon will be flagged.
      
      ---
      
      ## Overrides (File-Specific Rules)
      
      ### Test Files, Config Files, and Generated Code
      
      ```jsonc
      {
        "linter": {
          "rules": {
            "recommended": true,
            "style": {
              "noDefaultExport": "warn",
              "useImportType": "error",
            },
          },
        },
        "overrides": [
          {
            // Test files: relax strictness
            "includes": [
              "**/*.test.ts",
              "**/*.test.tsx",
              "**/*.spec.ts",
              "**/__tests__/**",
            ],
            "linter": {
              "rules": {
                "suspicious": {
                  "noExplicitAny": "off",
                },
                "style": {
                  "noDefaultExport": "off",
                },
              },
              "domains": {
                "test": "recommended",
              },
            },
          },
          {
            // Config files: allow default exports (bundler configs, etc.)
            "includes": ["*.config.ts", "*.config.mjs", "*.config.js"],
            "linter": {
              "rules": {
                "style": {
                  "noDefaultExport": "off",
                },
              },
            },
          },
          {
            // Generated files: disable linting and formatting
            "includes": ["**/generated/**", "**/*.generated.ts"],
            "linter": {
              "enabled": false,
            },
            "formatter": {
              "enabled": false,
            },
          },
        ],
      }
      ```
      
      **Why good:** Production code stays strict, test files get appropriate relaxations, config files allow framework-required default exports, generated code is completely excluded from processing
      
      ---
      
      ## Custom Import Ordering
      
      ### React Project with Company Packages
      
      ```jsonc
      {
        "assist": {
          "actions": {
            "source": {
              "organizeImports": {
                "level": "on",
                "options": {
                  "groups": [
                    ":NODE:",
                    ":PACKAGE:",
                    ":BLANK_LINE:",
                    ["@company/**"],
                    ":BLANK_LINE:",
                    ":ALIAS:",
                    ":PATH:",
                  ],
                },
              },
            },
          },
        },
      }
      ```
      
      **Result:**
      
      ```typescript
      import { readFileSync } from "node:fs";
      
      import { z } from "zod";
      
      import { apiClient } from "@company/api-client";
      import { Button } from "@company/ui";
      
      import { useAuth } from "@/hooks/use-auth";
      import { formatDate } from "../utils/date";
      import { UserCard } from "./user-card";
      ```
      
      ### Separating Type Imports
      
      ```jsonc
      {
        "assist": {
          "actions": {
            "source": {
              "organizeImports": {
                "level": "on",
                "options": {
                  "groups": [{ "type": false }, ":BLANK_LINE:", { "type": true }],
                },
              },
            },
          },
        },
      }
      ```
      
      **Result:**
      
      ```typescript
      import { z } from "zod";
      import { clsx } from "clsx";
      import { Button } from "./button";
      
      import type { User } from "../types/user";
      import type { Config } from "@company/shared";
      ```
      
      ---
      
      ## See Also
      
      - [SKILL.md](../SKILL.md) for core patterns and philosophy
      - [reference.md](../reference.md) for rule groups and severity values
      
      **Official Documentation:**
      
      - [Biome Linter Rules](https://biomejs.dev/linter/)
      - [Biome Suppressions](https://biomejs.dev/analyzer/suppressions/)
      - [Biome Import Organizer](https://biomejs.dev/assist/actions/organize-imports/)
      
    • migration.md 4.2 KB
      # Biome -- Migration from ESLint + Prettier
      
      > Step-by-step migration guide, rule mapping, and package cleanup. Reference from [SKILL.md](../SKILL.md).
      
      **Related examples:**
      
      - [core.md](core.md) -- Installation, biome.json config, editor integration
      - [linting.md](linting.md) -- Lint rules, domains, suppressions, overrides
      - [formatting.md](formatting.md) -- Formatter config, Prettier compatibility
      - [ci.md](ci.md) -- CI pipelines, git hooks, staged files
      
      ---
      
      ## Automated Migration
      
      ```bash
      # Step 1: Migrate Prettier settings (indent, quotes, line width)
      npx @biomejs/biome migrate prettier --write
      
      # Step 2: Migrate ESLint rules (maps to Biome equivalents)
      npx @biomejs/biome migrate eslint --write
      
      # Step 3: Include rules that are "inspired by" ESLint (not exact matches)
      npx @biomejs/biome migrate eslint --write --include-inspired
      
      # Step 4: Enable VCS integration (ESLint respects .gitignore by default)
      # Add to biome.json manually:
      # "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true }
      
      # Step 5: Verify migration
      npx @biomejs/biome check .
      
      # Step 6: Remove old tooling
      npm uninstall eslint prettier eslint-config-prettier eslint-plugin-only-warn \
        @eslint/js typescript-eslint eslint-plugin-react eslint-plugin-jsx-a11y
      
      # Step 7: Remove old config files
      rm -f .eslintrc* eslint.config.* .prettierrc* prettier.config.* .eslintignore .prettierignore
      ```
      
      ---
      
      ## Manual Migration Checklist
      
      | ESLint + Prettier                            | Biome Equivalent                              |
      | -------------------------------------------- | --------------------------------------------- |
      | `.eslintrc.json` / `eslint.config.ts`        | `biome.json`                                  |
      | `.prettierrc` / `prettier.config.mjs`        | `biome.json` (formatter section)              |
      | `.eslintignore`                              | `biome.json` files.includes with `!` patterns |
      | `.prettierignore`                            | `biome.json` files.includes with `!` patterns |
      | `eslint-config-prettier`                     | Not needed (no formatter/linter conflicts)    |
      | `eslint-plugin-only-warn`                    | Set rule severity to `"warn"`                 |
      | `eslint-plugin-import`                       | `assist.actions.source.organizeImports`       |
      | `@typescript-eslint/parser`                  | Built-in TypeScript support                   |
      | `@typescript-eslint/consistent-type-imports` | `style/useImportType`                         |
      | `@typescript-eslint/no-unused-vars`          | `correctness/noUnusedVariables`               |
      | `import/no-default-export`                   | `style/noDefaultExport`                       |
      | `no-console`                                 | `nursery/noConsole`                           |
      
      ---
      
      ## Removing Unnecessary Packages
      
      After migration, these packages are no longer needed:
      
      ```bash
      # Core tools (replaced by Biome)
      npm uninstall eslint prettier
      
      # ESLint plugins (handled by Biome rules)
      npm uninstall @eslint/js typescript-eslint eslint-config-prettier
      npm uninstall eslint-plugin-only-warn eslint-plugin-react
      npm uninstall eslint-plugin-jsx-a11y eslint-plugin-unicorn
      npm uninstall eslint-plugin-import eslint-plugin-simple-import-sort
      
      # Prettier plugins
      npm uninstall @prettier/sync prettier-plugin-tailwindcss
      ```
      
      ---
      
      ## Full Migration vs Hybrid Approach
      
      ```
      Migrating from ESLint + Prettier?
      |-- Standard rules only (recommended + typescript-eslint)?
      |   +-- Full migration to Biome (Biome covers these)
      |-- Using framework-specific ESLint plugins?
      |   |-- React/JSX-a11y/Unicorn?
      |   |   +-- Full migration (Biome has equivalent rules)
      |   |-- Custom/niche plugins?
      |   |   +-- Hybrid: Biome format + ESLint for custom rules
      |   +-- Many custom rules with specific options?
      |       +-- Hybrid approach (migrate incrementally)
      +-- Just want faster formatting?
          +-- Replace Prettier with Biome format, keep ESLint
      ```
      
      ---
      
      ## See Also
      
      - [SKILL.md](../SKILL.md) for core patterns and philosophy
      - [formatting.md](formatting.md) for Prettier option name mapping
      
      **Official Documentation:**
      
      - [Biome Migration Guide](https://biomejs.dev/guides/migrate-eslint-prettier/)
      - [Biome Upgrade to v2 Guide](https://biomejs.dev/guides/upgrade-to-biome-v2/)
      
    • setup.md 50 B
      This file has been renamed to [core.md](core.md).
      
  • reference.md 12.8 KB
    # Biome Quick Reference
    
    > CLI commands, configuration options, and rule groups for Biome v2.4.x. See [SKILL.md](SKILL.md) for core patterns and [examples/](examples/) for practical examples.
    
    ---
    
    ## CLI Commands
    
    ### Primary Commands
    
    | Command                  | Purpose                                          | Key Flags                                      |
    | ------------------------ | ------------------------------------------------ | ---------------------------------------------- |
    | `biome check .`          | Run lint + format + organize imports (read-only) | `--write`, `--unsafe`, `--staged`, `--changed` |
    | `biome check --write .`  | Run everything with auto-fix                     | `--unsafe` (include unsafe fixes)              |
    | `biome format .`         | Format only (read-only)                          | `--write`                                      |
    | `biome format --write .` | Format with auto-fix                             |                                                |
    | `biome lint .`           | Lint only (read-only)                            | `--write`, `--only`, `--skip`                  |
    | `biome lint --write .`   | Lint with safe fixes                             | `--unsafe`                                     |
    | `biome ci .`             | CI mode (read-only, no `--write`)                | `--reporter`, `--error-on-warnings`            |
    
    ### Setup and Migration
    
    | Command                                           | Purpose                                 |
    | ------------------------------------------------- | --------------------------------------- |
    | `biome init`                                      | Create default biome.json               |
    | `biome migrate --write`                           | Upgrade config between major versions   |
    | `biome migrate eslint --write`                    | Convert ESLint config to biome.json     |
    | `biome migrate prettier --write`                  | Convert Prettier config to biome.json   |
    | `biome migrate eslint --write --include-inspired` | Include inspired (non-equivalent) rules |
    
    ### Utility Commands
    
    | Command                  | Purpose                                       |
    | ------------------------ | --------------------------------------------- |
    | `biome explain <rule>`   | Show documentation for a rule                 |
    | `biome rage`             | Output debugging information                  |
    | `biome search <pattern>` | Search code with Grit patterns (experimental) |
    | `biome clean`            | Remove daemon logs                            |
    | `biome start`            | Start daemon server                           |
    | `biome stop`             | Stop daemon server                            |
    
    ---
    
    ## Common Flags
    
    | Flag                          | Commands                | Purpose                                                    |
    | ----------------------------- | ----------------------- | ---------------------------------------------------------- |
    | `--write`                     | check, format, lint     | Apply fixes to files                                       |
    | `--unsafe`                    | check, lint             | Include unsafe (behavior-changing) fixes                   |
    | `--staged`                    | check, format, lint     | Process only git staged files                              |
    | `--changed`                   | check, format, lint, ci | Process files changed since default branch                 |
    | `--since=<branch>`            | check, format, lint, ci | Process files changed since specified branch               |
    | `--only=<group>`              | check, lint, ci         | Run only specific rule group(s)                            |
    | `--skip=<rule>`               | check, lint, ci         | Skip specific rule(s)                                      |
    | `--reporter=<fmt>`            | all                     | Output format: default, json, github, gitlab, junit, sarif |
    | `--error-on-warnings`         | all                     | Exit non-zero on warnings                                  |
    | `--max-diagnostics=<n>`       | all                     | Limit number of diagnostics shown                          |
    | `--verbose`                   | all                     | Verbose output                                             |
    | `--no-errors-on-unmatched`    | all                     | Suppress errors when no files match                        |
    | `--files-ignore-unknown=true` | all                     | Skip unsupported file types                                |
    | `--config-path=<path>`        | all                     | Specify config file location                               |
    | `--colors=off`                | all                     | Disable colored output                                     |
    | `--profile-rules`             | check, lint             | Profile rule execution time (v2.4+)                        |
    
    ---
    
    ## Formatter Configuration Options
    
    ### Global Options (All Languages)
    
    | Option              | Type                         | Default  | Notes                           |
    | ------------------- | ---------------------------- | -------- | ------------------------------- |
    | `enabled`           | boolean                      | `true`   | Enable/disable formatting       |
    | `indentStyle`       | `"tab"` \| `"space"`         | `"tab"`  | **Biome defaults to tabs**      |
    | `indentWidth`       | number                       | `2`      | Spaces per indent level         |
    | `lineWidth`         | number                       | `80`     | Maximum line width              |
    | `lineEnding`        | `"lf"` \| `"crlf"` \| `"cr"` | `"lf"`   | Line ending character           |
    | `bracketSpacing`    | boolean                      | `true`   | Spaces inside `{ }`             |
    | `attributePosition` | `"auto"` \| `"multiline"`    | `"auto"` | HTML/JSX attribute position     |
    | `useEditorconfig`   | boolean                      | `false`  | Respect .editorconfig           |
    | `formatWithErrors`  | boolean                      | `false`  | Format files with syntax errors |
    
    ### JavaScript/TypeScript Options
    
    | Option             | Type                           | Default      | Notes                        |
    | ------------------ | ------------------------------ | ------------ | ---------------------------- |
    | `quoteStyle`       | `"single"` \| `"double"`       | `"double"`   | String quote style           |
    | `jsxQuoteStyle`    | `"single"` \| `"double"`       | `"double"`   | JSX attribute quote style    |
    | `quoteProperties`  | `"asNeeded"` \| `"preserve"`   | `"asNeeded"` | Object property quoting      |
    | `trailingCommas`   | `"all"` \| `"es5"` \| `"none"` | `"all"`      | Trailing comma behavior      |
    | `semicolons`       | `"always"` \| `"asNeeded"`     | `"always"`   | Semicolon insertion          |
    | `arrowParentheses` | `"always"` \| `"asNeeded"`     | `"always"`   | Arrow function parens        |
    | `bracketSameLine`  | boolean                        | `false`      | JSX closing `>` on same line |
    
    ### JSON Options
    
    | Option           | Type                | Default  | Notes                |
    | ---------------- | ------------------- | -------- | -------------------- |
    | `trailingCommas` | `"none"` \| `"all"` | `"none"` | JSON trailing commas |
    
    ---
    
    ## Linter Rule Groups
    
    | Group           | Purpose                         | Default Severity      |
    | --------------- | ------------------------------- | --------------------- |
    | `accessibility` | Prevents a11y problems          | error (recommended)   |
    | `complexity`    | Simplifies complex code         | error (recommended)   |
    | `correctness`   | Detects guaranteed errors       | error (recommended)   |
    | `nursery`       | Experimental rules              | off (opt-in required) |
    | `performance`   | Catches inefficient patterns    | error (recommended)   |
    | `security`      | Identifies security flaws       | error (recommended)   |
    | `style`         | Enforces consistent code style  | warn (recommended)    |
    | `suspicious`    | Flags likely incorrect patterns | error (recommended)   |
    
    ### Rule Severity Values
    
    | Level     | CLI Exit | Purpose                        |
    | --------- | -------- | ------------------------------ |
    | `"off"`   | N/A      | Rule disabled                  |
    | `"on"`    | varies   | Default severity for that rule |
    | `"info"`  | 0        | Informational diagnostic       |
    | `"warn"`  | 0        | Non-blocking warning           |
    | `"error"` | 1        | Blocking error                 |
    
    ### Domains (Technology-Specific)
    
    | Domain    | Detected From               | Purpose                                                        |
    | --------- | --------------------------- | -------------------------------------------------------------- |
    | `react`   | react in package.json       | React-specific rules                                           |
    | `solid`   | solid-js in package.json    | SolidJS-specific rules                                         |
    | `test`    | vitest/jest in package.json | Test-specific rules                                            |
    | `project` | Manual opt-in               | Cross-file analysis (module graph scanning)                    |
    | `types`   | Manual opt-in               | Type inference rules (v2.4+, ~75% tsc coverage for type rules) |
    
    ---
    
    ## Suppression Comment Syntax
    
    | Type        | Syntax                                 | Scope                        |
    | ----------- | -------------------------------------- | ---------------------------- |
    | Inline      | `// biome-ignore <spec>: reason`       | Next line                    |
    | File-wide   | `// biome-ignore-all <spec>: reason`   | Entire file (must be at top) |
    | Range start | `// biome-ignore-start <spec>: reason` | Until matching end           |
    | Range end   | `// biome-ignore-end <spec>: reason`   | Ends matching range          |
    
    ### Specifier Levels
    
    | Level    | Example                      |
    | -------- | ---------------------------- |
    | Category | `lint`, `format`, `assist`   |
    | Group    | `lint/suspicious`            |
    | Rule     | `lint/suspicious/noDebugger` |
    
    ---
    
    ## Configuration File Resolution
    
    **Search order:** `biome.json` > `biome.jsonc` > `.biome.json` > `.biome.jsonc`
    
    **Search locations:**
    
    1. Current working directory
    2. Parent directories (recursively)
    3. Home config directory (`$XDG_CONFIG_HOME/biome`, etc.)
    
    **Nested configs:** Files use the nearest `biome.json` in parent hierarchy. Child configs use `"root": false`.
    
    ---
    
    ## Biome vs Prettier: Option Name Mapping
    
    | Prettier          | Biome                     | Notes                |
    | ----------------- | ------------------------- | -------------------- |
    | `printWidth`      | `lineWidth`               |                      |
    | `tabWidth`        | `indentWidth`             |                      |
    | `useTabs`         | `indentStyle: "tab"`      |                      |
    | `semi`            | `semicolons: "always"`    | Different naming     |
    | `singleQuote`     | `quoteStyle: "single"`    | Different naming     |
    | `trailingComma`   | `trailingCommas`          | Plural in Biome      |
    | `bracketSpacing`  | `bracketSpacing`          | Same                 |
    | `bracketSameLine` | `bracketSameLine`         | Same                 |
    | `arrowParens`     | `arrowParentheses`        | Longer name in Biome |
    | `endOfLine`       | `lineEnding`              | Different naming     |
    | `jsxSingleQuote`  | `jsxQuoteStyle: "single"` | Different naming     |
    
    ---
    
    ## Version History
    
    | Version | Release  | Key Features                                                         |
    | ------- | -------- | -------------------------------------------------------------------- |
    | v2.4.x  | Feb 2026 | Embedded snippets, HTML a11y rules, types domain, rule profiler      |
    | v2.0    | Jun 2025 | Type-aware linting, nested configs, import organizer revamp, plugins |
    | v1.9.x  | 2024     | CSS support, GraphQL support, `--staged` flag                        |
    | v1.0    | Aug 2023 | Initial stable release (fork of Rome)                                |
    
    ---
    
    ## See Also
    
    - [examples/core.md](examples/core.md) for installation, biome.json, editor integration
    - [examples/linting.md](examples/linting.md) for lint rules, suppressions, overrides
    - [examples/formatting.md](examples/formatting.md) for formatter options, Prettier mapping
    - [examples/ci.md](examples/ci.md) for CI pipelines, git hooks, staged files
    - [examples/migration.md](examples/migration.md) for ESLint/Prettier migration
    - [SKILL.md](SKILL.md) for core patterns and philosophy
    
    **Official Documentation:**
    
    - [Biome Configuration Reference](https://biomejs.dev/reference/configuration/)
    - [Biome CLI Reference](https://biomejs.dev/reference/cli/)
    - [Biome Linter Rules](https://biomejs.dev/linter/)
    - [Biome Migration Guide](https://biomejs.dev/guides/migrate-eslint-prettier/)
    - [Biome Git Hooks](https://biomejs.dev/recipes/git-hooks/)
    - [Biome CI Integration](https://biomejs.dev/recipes/continuous-integration/)
    - [Biome VS Code Extension](https://biomejs.dev/reference/vscode/)
    
  • SKILL.md 19.6 KB
    ---
    name: shared-tooling-biome
    description: Biome v2 unified linter, formatter, and import organizer — single Rust-powered tool replacing ESLint + Prettier with 97% Prettier compatibility and 20x faster performance
    ---
    
    # Biome
    
    > **Quick Guide:** Biome is a unified linter, formatter, and import organizer for JavaScript, TypeScript, JSX, TSX, JSON, CSS, and GraphQL. Single Rust binary replaces ESLint + Prettier with 97% Prettier compatibility. Use `biome.json` for all configuration. Run `biome check --write` to lint, format, and organize imports in one pass. Use `biome ci` in pipelines.
    >
    > **Current stable version:** Biome v2.4.x (March 2026). Biome v2 introduced type-aware linting, nested configs, and a revamped import organizer.
    
    ---
    
    <critical_requirements>
    
    ## CRITICAL: Before Using This Skill
    
    > **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)
    
    **(You MUST use `biome.json` or `biome.jsonc` for ALL configuration — Biome does not use JavaScript config files)**
    
    **(You MUST pin Biome to an exact version with `--save-exact` — Biome formatting can change between versions)**
    
    **(You MUST use `biome ci` in CI pipelines, NOT `biome check` — `ci` is read-only with no `--write` flag)**
    
    **(You MUST use `biome check --write` for local development — runs linter, formatter, and import organizer in one pass)**
    
    **(You MUST include `$schema` in biome.json for editor autocompletion and validation)**
    
    </critical_requirements>
    
    ---
    
    **Auto-detection:** Biome, biome.json, biome.jsonc, @biomejs/biome, biome check, biome lint, biome format, biome ci, biome-ignore, organizeImports, biome migrate
    
    **When to use:**
    
    - Setting up a unified linter + formatter for JavaScript/TypeScript projects
    - Replacing ESLint + Prettier with a single, faster tool
    - Greenfield projects wanting zero-config or minimal-config setup
    - Large codebases where linting/formatting speed matters
    - Configuring import organizing with custom group ordering
    - Migrating from ESLint and/or Prettier to Biome
    - Setting up CI pipelines with `biome ci`
    - Configuring pre-commit hooks with Biome's `--staged` flag
    
    **When NOT to use:**
    
    - Projects requiring ESLint plugins with no Biome equivalent (e.g., custom framework-specific plugins)
    - Projects heavily invested in custom ESLint rules that cannot be replicated
    - Projects needing Markdown, YAML, or TOML formatting (Biome does not support these yet)
    - Runtime code (this is build-time tooling only)
    - Git hooks framework setup (Husky/Lefthook configuration is a separate concern)
    - TypeScript compiler configuration (`tsconfig.json` is a separate concern)
    
    **Key patterns covered:**
    
    - biome.json configuration with formatter, linter, and assist settings
    - Linter rule groups (recommended, all, nursery) and severity levels
    - Formatter configuration (indent style, line width, quotes, semicolons)
    - Import organizer with custom group ordering
    - CLI commands: check, format, lint, ci, migrate
    - Migration from ESLint + Prettier
    - Git hooks integration (Husky, Lefthook, `--staged` flag)
    - CI integration with GitHub Actions and GitLab CI
    - Editor integration (VS Code, JetBrains)
    - Suppression comments (`biome-ignore`, `biome-ignore-all`, range suppressions)
    - Nested configuration for monorepos
    - Overrides for file-specific settings
    
    ---
    
    ## Examples
    
    - [Setup & Configuration](examples/core.md) — Installation, biome.json, VS Code, monorepos, framework configs
    - [Linting Rules](examples/linting.md) — Rule groups, domains, suppressions, overrides, import ordering
    - [Formatting](examples/formatting.md) — Formatter options, Prettier compatibility, option mapping
    - [CI & Git Hooks](examples/ci.md) — GitHub Actions, GitLab CI, Husky, Lefthook, staged files
    - [Migrating from ESLint/Prettier](examples/migration.md) — Automated migration, rule mapping, package cleanup
    
    **Other resources:**
    
    - [CLI Quick Reference](reference.md) — All CLI commands, flags, and configuration option tables
    
    ---
    
    <philosophy>
    
    ## Philosophy
    
    Biome unifies linting, formatting, and import organizing into a **single tool with a single configuration file**. Built in Rust, it delivers 20x faster performance than ESLint + Prettier while maintaining 97% Prettier compatibility.
    
    **Core principles:**
    
    1. **One tool, one config** — biome.json replaces .eslintrc, prettier.config, and import sorting plugins
    2. **Sensible defaults** — Biome works out of the box with recommended rules enabled; zero-config is a valid setup
    3. **Speed as a feature** — Rust-powered binary processes large codebases in milliseconds, not seconds
    4. **Unified commands** — `biome check --write` runs everything in one pass (lint + format + organize imports)
    5. **Safe by default** — Safe fixes apply automatically; unsafe fixes require explicit `--unsafe` flag
    
    </philosophy>
    
    ---
    
    <patterns>
    
    ## Core Patterns
    
    ### Pattern 1: Basic biome.json Configuration
    
    Every Biome project starts with a `biome.json` at the project root. Use `biome init` to scaffold one, then customize.
    
    ```bash
    # Install Biome (always pin exact version)
    npm install --save-dev --save-exact @biomejs/biome
    
    # Create default biome.json
    npx @biomejs/biome init
    ```
    
    ```jsonc
    // biome.json — minimal recommended setup
    {
      "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
      "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
      "formatter": { "indentStyle": "space", "indentWidth": 2, "lineWidth": 100 },
      "linter": { "rules": { "recommended": true } },
      "assist": {
        "enabled": true,
        "actions": { "source": { "organizeImports": "on" } },
      },
    }
    ```
    
    **Why good:** `$schema` enables editor autocompletion, VCS integration respects `.gitignore`, explicit `indentStyle: "space"` avoids Biome's tab default, recommended rules provide a strong baseline
    
    ```jsonc
    // BAD: No schema, no VCS, relying on defaults that differ from Prettier
    { "linter": { "enabled": true } }
    ```
    
    **Why bad:** Missing `$schema` loses autocompletion, no VCS means linting node_modules, Biome defaults to tabs which surprises Prettier migrants
    
    > **Full example:** See [examples/core.md](examples/core.md) for a production-ready biome.json with overrides, framework configs, and monorepo setup.
    
    ---
    
    ### Pattern 2: Linter Rules Configuration
    
    Biome provides 459+ rules across 8 groups (`accessibility`, `complexity`, `correctness`, `nursery`, `performance`, `security`, `style`, `suspicious`). Rules default to `recommended` — a curated subset of safe, stable rules. Severity levels: `"off"`, `"on"`, `"info"`, `"warn"`, `"error"`. See [reference.md](reference.md#linter-rule-groups) for the full rule groups and severity tables.
    
    #### Domains (Technology-Specific Rules)
    
    Biome v2 introduces domains that group rules by technology. Domains auto-detect from `package.json` dependencies.
    
    ```jsonc
    { "linter": { "domains": { "react": "recommended", "test": "recommended" } } }
    ```
    
    > **Full examples:** See [examples/linting.md](examples/linting.md) for rule configuration, suppressions, overrides, and import ordering.
    
    ---
    
    ### Pattern 3: Formatter Configuration
    
    Biome's formatter achieves 97% Prettier compatibility. Global settings apply to all languages; language-specific settings override globals. **Biome defaults to tabs** — set `indentStyle: "space"` explicitly when migrating from Prettier.
    
    ```jsonc
    {
      "formatter": { "indentStyle": "space", "indentWidth": 2, "lineWidth": 100 },
      "javascript": {
        "formatter": { "quoteStyle": "double", "semicolons": "always" },
      },
      "json": { "formatter": { "trailingCommas": "none" } },
      "css": { "formatter": { "enabled": true } },
    }
    ```
    
    > **Full reference:** See [examples/formatting.md](examples/formatting.md) for all options, Prettier mapping, and language-specific settings.
    
    ---
    
    ### Pattern 4: Import Organizer
    
    Biome v2 revamped the import organizer with custom group ordering. Configure under `assist.actions.source.organizeImports`.
    
    ```jsonc
    {
      "assist": {
        "actions": {
          "source": {
            "organizeImports": {
              "level": "on",
              "options": {
                "groups": [
                  [":BUN:", ":NODE:"],
                  ":PACKAGE:",
                  ":BLANK_LINE:",
                  ["@company/**"],
                  ":BLANK_LINE:",
                  ":ALIAS:",
                  ":PATH:",
                  ":BLANK_LINE:",
                  { "type": true },
                ],
                "identifierOrder": "natural",
              },
            },
          },
        },
      },
    }
    ```
    
    **Key options:** `identifierOrder` controls named import sorting — `"natural"` (default, e.g. `var1, var2, var11`) or `"lexicographic"` (strict alphabetical). Groups accept predefined matchers, glob patterns (`"@my/lib/**"`), object matchers (`{ "type": true, "source": ["@my/lib"] }`), or arrays combining any of these.
    
    #### Predefined Groups
    
    | Group                     | Matches                                    |
    | ------------------------- | ------------------------------------------ |
    | `:NODE:`                  | Node.js built-ins and `node:` protocol     |
    | `:BUN:`                   | Bun-specific modules                       |
    | `:PACKAGE:`               | Scoped and bare npm packages               |
    | `:PACKAGE_WITH_PROTOCOL:` | Packages with a protocol prefix            |
    | `:ALIAS:`                 | Aliased imports (`@/`, `#`, `~`, `$`, `%`) |
    | `:PATH:`                  | Absolute and relative path imports         |
    | `:URL:`                   | HTTP/HTTPS imports                         |
    | `:BLANK_LINE:`            | Visual separator between groups            |
    
    > **Full examples:** See [examples/linting.md](examples/linting.md#custom-import-ordering) for import ordering with results.
    
    ---
    
    ### Pattern 5: CLI Commands
    
    Use `check` locally, `ci` in pipelines. Key commands:
    
    ```bash
    npx biome check --write .          # Lint + format + organize imports (auto-fix)
    npx biome ci .                     # CI mode (read-only, optimized for pipelines)
    npx biome check --staged --write . # Pre-commit hooks (only staged files)
    npx biome check --changed --since=main .  # Changed files only
    ```
    
    > **Full reference:** See [examples/ci.md](examples/ci.md) for complete CLI usage, filtering, and reporting options.
    
    ---
    
    ### Pattern 6: Suppression Comments
    
    Biome uses `biome-ignore` comments with required explanations.
    
    ```typescript
    // biome-ignore lint/suspicious/noDebugger: needed for local debugging
    debugger;
    
    // biome-ignore-all lint/style/noDefaultExport: framework requires default export (top of file only)
    
    // biome-ignore-start lint/suspicious/noDoubleEquals: legacy section
    // biome-ignore-end lint/suspicious/noDoubleEquals: legacy section
    ```
    
    See [reference.md](reference.md#suppression-comment-syntax) for the full suppression syntax table and specifier levels. See [examples/linting.md](examples/linting.md#suppression-comments) for inline, file-level, and range suppression examples.
    
    ---
    
    ### Pattern 7: Nested Configuration (Monorepos)
    
    Biome v2 supports nested `biome.json` files. Each subdirectory can override the root config.
    
    ```jsonc
    // packages/my-app/biome.json — inherits from root
    { "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json", "extends": "//" }
    ```
    
    ```jsonc
    // packages/legacy-lib/biome.json — relaxes rules
    {
      "$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
      "root": false,
      "linter": { "rules": { "suspicious": { "noExplicitAny": "off" } } },
    }
    ```
    
    **Why good:** `"extends": "//"` shorthand inherits root config, `"root": false` marks as child, each package can relax or tighten rules independently
    
    > **Full examples:** See [examples/core.md](examples/core.md#monorepo-nested-configuration) for root + child config patterns.
    
    ---
    
    ### Pattern 8: Overrides (File-Specific Rules)
    
    Use `overrides` for file-pattern-specific configuration without nested config files.
    
    ```jsonc
    {
      "overrides": [
        {
          "includes": ["**/*.test.ts", "**/*.test.tsx"],
          "linter": { "rules": { "suspicious": { "noExplicitAny": "off" } } },
        },
        {
          "includes": ["**/app/**/page.tsx", "**/app/**/layout.tsx"],
          "linter": { "rules": { "style": { "noDefaultExport": "off" } } },
        },
      ],
    }
    ```
    
    **Why good:** Overrides eliminate suppression comments in every file, test files get relaxed rules, framework conventions handled declaratively
    
    > **Full examples:** See [examples/linting.md](examples/linting.md#overrides-file-specific-rules) for test, config, and generated file overrides.
    
    </patterns>
    
    ---
    
    <performance>
    
    ## Performance
    
    Biome is written in Rust and processes files in parallel, making it significantly faster than JavaScript-based alternatives.
    
    | Tool              | Format Time (1000 files) | Lint Time (1000 files) |
    | ----------------- | ------------------------ | ---------------------- |
    | Biome             | ~100ms                   | ~200ms                 |
    | Prettier          | ~2000ms                  | N/A                    |
    | ESLint            | N/A                      | ~3000ms                |
    | ESLint + Prettier | ~5000ms                  | ~5000ms                |
    
    _Approximate benchmarks. Actual performance varies by project size and rule configuration._
    
    **Performance Tips:**
    
    - **Use `biome check`** instead of running `biome format` and `biome lint` separately — single pass is faster
    - **Enable VCS integration** to automatically skip ignored files (`.gitignore`)
    - **Use `--staged` or `--changed`** in hooks and CI to process only affected files
    - **Be selective with nursery rules** — some experimental rules may impact performance
    - **Use `--profile-rules`** (v2.4+) to identify slow lint rules in your configuration
    
    **Type-Aware Linting Performance:**
    
    Biome v2 introduced type-aware linting without the TypeScript compiler. Enable selectively:
    
    - **Default scan** discovers nested configs only (fast)
    - **Project domain scan** indexes the full module graph (slower, but still faster than tsc)
    - **Types domain scan** adds type inference (most comprehensive, most expensive)
    
    </performance>
    
    ---
    
    <decision_framework>
    
    ## Decision Framework
    
    ### Biome vs ESLint + Prettier
    
    ```
    Need linting and formatting?
    |-- Greenfield project?
    |   |-- Want simplest possible setup? -> Biome (one tool, one config)
    |   |-- Need niche ESLint plugins? -> ESLint + Prettier
    |   +-- Speed is important? -> Biome (20x faster)
    |-- Existing ESLint + Prettier project?
    |   |-- Happy with current setup? -> Stay with ESLint + Prettier
    |   |-- Config complexity is a pain? -> Migrate to Biome
    |   |-- Need ESLint plugins without Biome equivalents? -> Stay
    |   +-- Want faster CI/pre-commit hooks? -> Biome (or hybrid)
    +-- Monorepo?
        |-- Need per-package lint configs? -> Biome v2 nested configs or ESLint 10
        +-- Speed bottleneck in CI? -> Biome
    ```
    
    ### Configuration Complexity
    
    ```
    How to configure Biome?
    |-- Just starting out? -> Run `biome init`, use defaults with recommended: true
    |-- Migrating from ESLint? -> Run `biome migrate eslint --write`
    |-- Migrating from Prettier? -> Run `biome migrate prettier --write`
    |-- Need per-file rules?
    |   |-- Different rules for test files? -> Use `overrides` in biome.json
    |   +-- Different rules per package? -> Use nested biome.json with "root": false
    +-- Need custom import ordering? -> Configure organizeImports.options.groups
    ```
    
    > **Full migration decision tree:** See [examples/migration.md](examples/migration.md#full-migration-vs-hybrid-approach).
    
    </decision_framework>
    
    ---
    
    <integration>
    
    ## Integration Guide
    
    **Works with:**
    
    - **JSX/TSX**: Full support with `react` domain for React-specific lint rules
    - **TypeScript**: Type-aware linting without tsc dependency (Biome v2+)
    - **CSS**: Linting enabled by default, formatting opt-in
    - **JSON/JSONC**: Full support including tsconfig.json, package.json
    - **GraphQL**: Linting enabled by default, formatting opt-in
    - **Vue/Svelte/Astro**: Experimental support via `html.experimentalFullSupportEnabled` (v2.4+)
    
    **Replaces / Conflicts with:**
    
    - **ESLint**: Biome replaces ESLint for linting (or use hybrid approach)
    - **Prettier**: Biome replaces Prettier for formatting
    - **eslint-plugin-import**: Biome's import organizer replaces import sorting plugins
    - **eslint-config-prettier**: Not needed — Biome has no formatter/linter conflicts
    
    > **CI/editor integration:** See [examples/ci.md](examples/ci.md) and [examples/core.md](examples/core.md#vs-code-integration).
    
    </integration>
    
    ---
    
    <red_flags>
    
    ## RED FLAGS
    
    **High Priority Issues:**
    
    - Using `biome check` in CI instead of `biome ci` (`check` allows `--write` which is dangerous in pipelines; `ci` is read-only)
    - Not pinning Biome version with `--save-exact` (formatting can change between minor versions, causing diff noise)
    - Missing `$schema` in biome.json (loses editor autocompletion, validation, and discoverability)
    - Using JavaScript config files instead of biome.json (Biome only supports JSON/JSONC configuration)
    - Running `biome format` and `biome lint` separately when `biome check` does both (wastes time, parses files twice)
    
    **Medium Priority Issues:**
    
    - Forgetting to set `indentStyle: "space"` when migrating from Prettier (Biome defaults to tabs)
    - Not enabling VCS integration (without it, Biome may process node_modules and dist)
    - Using `--unsafe` without reviewing changes (unsafe fixes can alter program behavior)
    - Not including `--no-errors-on-unmatched` in git hooks (causes failures when no matching files are staged)
    - Enabling all nursery rules (they are experimental and may have bugs or performance issues)
    
    **Common Mistakes:**
    
    - Using `"root": true` in a nested config (this is the default; use `"root": false` for child configs)
    - Expecting Markdown/YAML formatting support (Biome does not support these languages yet)
    - Not running `biome migrate --write` when upgrading major versions (config schema changes between v1 and v2)
    - Suppression comments without explanations (`biome-ignore lint:` requires text after the colon)
    
    **Gotchas & Edge Cases:**
    
    - Biome defaults to tabs, not spaces — always set `indentStyle` explicitly when migrating from Prettier
    - CSS and GraphQL formatting is disabled by default — must opt in with `"formatter": { "enabled": true }`
    - `biome-ignore-all` must be at the top of the file — placing it mid-file triggers an unused suppression warning
    - Import organizer is part of `assist`, not `linter` — configure under `assist.actions.source.organizeImports`
    - The `--staged` flag makes lint-staged unnecessary for Biome-only setups (since Biome v1.7.0+)
    - Type-aware linting (project/types domains) triggers file scanning which can slow down first runs on large projects
    - `biome migrate eslint --write` does not migrate inspired rules by default — use `--include-inspired` to include them
    - Range suppressions (`biome-ignore-start`/`biome-ignore-end`) must have matching rule specifiers
    - Biome treats all JS/TS/JSX/TSX under the `javascript` config key — there is no separate `typescript` section
    - Configuration files named `.biome.json` (with leading dot) are also discovered (v2.4+)
    
    </red_flags>
    
    ---
    
    <critical_reminders>
    
    ## CRITICAL REMINDERS
    
    > **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)
    
    **(You MUST use `biome.json` or `biome.jsonc` for ALL configuration — Biome does not use JavaScript config files)**
    
    **(You MUST pin Biome to an exact version with `--save-exact` — Biome formatting can change between versions)**
    
    **(You MUST use `biome ci` in CI pipelines, NOT `biome check` — `ci` is read-only with no `--write` flag)**
    
    **(You MUST use `biome check --write` for local development — runs linter, formatter, and import organizer in one pass)**
    
    **(You MUST include `$schema` in biome.json for editor autocompletion and validation)**
    
    **Failure to follow these rules will cause inconsistent formatting, broken CI pipelines, and missed lint errors.**
    
    </critical_reminders>
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related