biome.json Configuration Reference

Last updated:

Biome replaces both Prettier and ESLint with a single Rust-powered tool and a single config file — biome.json. This reference covers every top-level key: formatter, linter, organizeImports, vcs, files, overrides, and the JSON/TypeScript language-specific subsections, with a complete example and migration paths from both tools.

1. Minimal biome.json

A minimal config that enables all defaults — useful as a starting point:

{
  "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
  "formatter": {
    "enabled": true,
    "indentStyle": "tab",
    "lineWidth": 80
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  },
  "organizeImports": {
    "enabled": true
  }
}

"recommended": true enables Biome's opinionated rule set — roughly analogous toeslint:recommended plus a curated subset of TypeScript rules. Run biome init to generate this file automatically.

2. Formatter Options

The formatter section controls how Biome rewrites whitespace and punctuation:

"formatter": {
  "enabled": true,
  "indentStyle": "space",   // "tab" (default) | "space"
  "indentWidth": 2,         // 1–8, default 2
  "lineWidth": 100,         // default 80
  "lineEnding": "lf",       // "lf" | "crlf" | "cr"
  "attributePosition": "auto" // "auto" | "multiline" (JSX attrs)
}

Language-specific sub-sections override the top-level formatter for individual file types:

"json": {
  "formatter": {
    "indentWidth": 2,
    "indentStyle": "space",
    "trailingCommas": "none"
  },
  "parser": {
    "allowComments": true,      // JSONC support
    "allowTrailingCommas": true
  }
},
"javascript": {
  "formatter": {
    "quoteStyle": "double",      // "double" | "single"
    "trailingCommas": "all",     // "all" | "es5" | "none"
    "semicolons": "always"       // "always" | "asNeeded"
  }
}

3. Linter Options and Rule Groups

Biome organizes rules into six groups. Each group can be toggled as a whole, or individual rules can be overridden:

"linter": {
  "enabled": true,
  "rules": {
    "recommended": true,
    "accessibility": {
      "recommended": true,
      "noAccessKey": "error"
    },
    "complexity": {
      "noForEach": "warn",
      "useLiteralKeys": "error"
    },
    "correctness": {
      "noUnusedVariables": "error",
      "useExhaustiveDependencies": "warn"
    },
    "performance": {
      "noAccumulatingSpread": "error"
    },
    "security": {
      "noDangerouslySetInnerHtml": "warn"
    },
    "style": {
      "useConst": "error",
      "useNamingConvention": "off"
    },
    "suspicious": {
      "noExplicitAny": "warn",
      "noDoubleEquals": "error"
    }
  }
}

Rule severity values are "off", "warn", and "error". Rules that accept options take an object: {"{"}"level": "error", "options": {"{"}...{"}"}{"}"}.

4. organizeImports

Import organization sorts and groups import statements. It runs as part of biome check --applyand biome check --apply-unsafe (for unsafe fixes):

"organizeImports": {
  "enabled": true
}

Biome's import sorter groups by: built-in Node modules, external packages, internal aliases (e.g., @/), relative imports. Within each group it sorts alphabetically. The sort is stable — reordering only happens when needed. There is currently no config for custom group order; if you need fine-grained import grouping, keep ESLint's import/order rule alongside Biome by disabling only Biome's organizeImports.

5. VCS Integration

VCS integration makes Biome aware of Git, enabling --changed mode (only check files changed vs a base branch) and respecting .gitignore:

"vcs": {
  "enabled": true,
  "clientKind": "git",
  "useIgnoreFile": true,
  "defaultBranch": "main"
}

With this config, biome check --changed --since=main only processes files touched since the branch diverged from main — essential for fast pre-commit hooks in large repos. "useIgnoreFile": true reads .gitignore so Biome automatically skips everything Git ignores (dist, build, node_modules).

6. Files and Overrides

The files section sets global inclusion/exclusion. overrides applies different settings to specific globs:

"files": {
  "include": ["src/**", "scripts/**"],
  "ignore": ["**/dist/**", "**/build/**", "**/generated/**"],
  "ignoreUnknown": true
},
"overrides": [
  {
    "include": ["**/*.test.ts", "**/*.spec.ts"],
    "linter": {
      "rules": {
        "style": { "useNamingConvention": "off" },
        "suspicious": { "noExplicitAny": "off" }
      }
    }
  },
  {
    "include": ["**/generated/**"],
    "formatter": { "enabled": false },
    "linter": { "enabled": false }
  }
]

Overrides apply on top of the top-level config in array order — later entries win. The includeglobs use gitignore-style patterns anchored to the project root.

7. Full Example biome.json

A production-ready config combining all sections:

{
  "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true,
    "defaultBranch": "main"
  },
  "files": {
    "ignoreUnknown": true,
    "ignore": ["dist", "build", ".next", "coverage"]
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100
  },
  "organizeImports": { "enabled": true },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": { "noUnusedVariables": "error" },
      "style": { "useConst": "error" },
      "suspicious": { "noExplicitAny": "warn" }
    }
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single",
      "trailingCommas": "es5",
      "semicolons": "always"
    }
  },
  "json": {
    "parser": { "allowComments": true },
    "formatter": { "indentWidth": 2 }
  },
  "overrides": [
    {
      "include": ["**/*.test.ts", "**/*.spec.ts"],
      "linter": {
        "rules": { "suspicious": { "noExplicitAny": "off" } }
      }
    }
  ]
}

Frequently Asked Questions

What is biome.json and what does it configure?

biome.json is the single configuration file for Biome — a fast, Rust-based toolchain that replaces both Prettier (formatter) and ESLint (linter) with one tool and one config. The file lives at the project root and controls four top-level systems: "formatter" (indentation, line width, quote style, trailing commas), "linter" (400+ rules across accessibility, complexity, correctness, performance, security, and style), "organizeImports" (automatic import sorting), and "vcs" (Git integration for staged-file workflows). Optional "files" and "overrides" sections handle inclusion/exclusion and per-glob rule overrides. When biome.json is absent, Biome falls back to built-in defaults, so no config is required to start — but the file unlocks project-specific tuning and is committed to version control so every contributor and CI run uses identical settings.

How do I migrate from Prettier to Biome formatter?

Biome ships a migration command: run `npx @biomejs/biome migrate prettier --write` at the project root. It reads .prettierrc / .prettierrc.json / prettier.config.js and converts the recognized options to biome.json equivalents — printWidth becomes "lineWidth", tabWidth becomes "indentWidth", singleQuote sets "quoteStyle", and so on. Options Biome does not support (htmlWhitespaceSensitivity, embeddedLanguageFormatting) are silently dropped. After migration, delete .prettierrc and remove the prettier package. A few formatting differences survive migration because Biome deliberately diverges from Prettier in certain edge cases (template-literal indentation, long ternary chains). Run `biome format --write .` and review the diff; most projects see zero or near-zero changes beyond the expected rule differences.

How do I migrate from ESLint to Biome linter?

Run `npx @biomejs/biome migrate eslint --write`. It reads .eslintrc* / eslint.config.js and maps rules it knows to biome.json linter rules under the appropriate group (correctness, suspicious, style, etc.). Rules ESLint has that Biome has not implemented are listed in the migration output so you can track coverage gaps. The most common gap: ESLint plugins for React hooks, testing-library, or import resolution have no Biome equivalent yet. The migration command also rewrites extends like "eslint:recommended" and "plugin:@typescript-eslint/recommended" to the Biome equivalents. After migration, remove eslint, @eslint/js, and any plugin packages. If you need both tools during a transition period, set "linter.enabled": false in biome.json and run ESLint separately, or vice versa.

What does the "overrides" section do in biome.json?

The "overrides" array lets you apply different formatter or linter settings to specific file globs. Each entry has a "include" array of glob patterns plus any subset of the top-level formatter/linter/organizeImports keys. Override entries are applied in order; later entries win. Common uses: disable formatting for generated files ("include": ["**/generated/**"], "formatter": {"enabled": false}); relax naming rules for test files ("include": ["**/*.test.ts"], "linter": {"rules": {"style": {"useNamingConvention": "off"}}}); apply different indent size to YAML ("include": ["**/*.yml"], "formatter": {"indentWidth": 2}). Glob syntax follows gitignore patterns. The "files.ignore" array handles global exclusion without a formatter/linter toggle — use it for node_modules, dist, and build artifacts.

How do I enable Biome in VS Code?

Install the "Biome" extension (biomejs.biome) from the VS Code Marketplace. Then configure VS Code to use Biome as the default formatter: open settings.json and add "[javascript]": {"editor.defaultFormatter": "biomejs.biome"}, "[typescript]": {"editor.defaultFormatter": "biomejs.biome"}, "[json]": {"editor.defaultFormatter": "biomejs.biome"}, and "editor.formatOnSave": true. For lint-on-save, add "editor.codeActionsOnSave": {"source.fixAll.biome": "explicit"}. The extension reads biome.json from the workspace root. If you have a monorepo with multiple biome.json files, the extension uses the closest parent biome.json relative to the open file. You can also set "biome.lspBin" in settings to point to a local binary if you want to pin a specific Biome version independently of the project's npm install.

How do I run Biome in CI?

The canonical CI command is `npx @biomejs/biome ci .` — it runs format checking, lint, and import organization in a single pass and exits non-zero on any violation. It does not write files, so it is safe in read-only CI environments. To check only formatting: `biome format .` (exits non-zero on diff). To check only lint: `biome lint .`. For staged-file workflows (pre-commit hooks), enable VCS integration in biome.json: "vcs": {"enabled": true, "clientKind": "git", "useIgnoreFile": true, "defaultBranch": "main"} and run `biome check --changed --since=main`. This tells Biome to only process files changed since the branch diverged from main, making pre-commit hooks fast even in large repos. Pair with lint-staged or Husky for automatic pre-commit enforcement.

Can Biome format JSON and JSONC files?

Yes. Biome formats JSON files by default when you run `biome format` or `biome check`. JSONC (JSON with Comments) requires "json": {"parser": {"allowComments": true}} in the biome.json formatter section. You can also allow trailing commas with "allowTrailingCommas": true — useful for tsconfig.json, .vscode/settings.json, and similar files that use the relaxed JSONC format. The JSON formatter respects the top-level "formatter" settings (indentWidth, lineWidth, indentStyle) but JSON-specific overrides live under the "json.formatter" key. One common override: format JSON with 2-space indent even when TypeScript uses tabs — add an "overrides" entry targeting "**/*.json" with "formatter": {"indentWidth": 2, "indentStyle": "space"}.

What is the "$schema" key in biome.json?

The "$schema" key points to the JSON Schema that describes all valid biome.json options. Biome publishes versioned schemas at https://biomejs.dev/schemas/<version>/schema.json — for example, "https://biomejs.dev/schemas/1.9.4/schema.json". When this key is present, editors that understand JSON Schema (VS Code with the JSON Language Features extension, JetBrains IDEs, Neovim with coc-json) provide autocomplete for all keys and values, inline documentation, and validation errors for typos or unsupported options. This is similar to the "$schema" key in tsconfig.json, .vscode/settings.json, or .github/workflows YAML. Always include it: it costs nothing, and it turns the config file into self-documenting, IDE-aware JSON.

Further reading and primary sources