Adopting Biome: Recommended Rules, Selective Categories, and CI Enforcement
Decide whether to use Biome's recommended lint baseline or selective rule categories, and enforce formatting with biome check and biome ci without breaking a legacy codebase.
02 Jan 2026, 05:29 UTC

Decision: adopt Biome as the project's formatter and linter
The decision is whether to replace separate formatting and linting tools with Biome, a single Rust-based CLI for JavaScript and TypeScript, and if so, which rule baseline to enable. Teams also need to decide whether to enforce Biome locally, in continuous integration, or both.
Useful takeaway: start with Biome's recommended rule baseline, apply biome check --write locally on feature branches, and block merges with biome ci in CI. Avoid nursery rules unless you can pin the Biome version and review churn.
Constraints and assumptions
- The repository contains JavaScript or TypeScript source files.
- Biome is installed as a development dependency and available to developers and CI.
- The team accepts an opinionated formatter with limited configuration options.
biome.jsoncuses JSONC, which is JSON with comments; standard JSON parsers will reject it.
Assume Biome is invoked from the project root with npx biome or a locally installed binary. No administrator privileges are required.
Rule baseline options compared
| Option | Behavior | Best suited for | Maintenance risk |
|---|---|---|---|
linter.rules.recommended |
Enables Biome's stable baseline across correctness, suspicious, style, and performance rule groups. | New adopters who want a ready-made starting point. | Low; recommended rules are stable between releases. |
| Selective categories | Enables only chosen groups such as correctness or suspicious while disabling others. | Teams migrating incrementally or avoiding noisy style rules. | Medium; the explicit list must be revisited when rules graduate from nursery. |
| Nursery rules | Enables unstable preview rules that may change or be removed. | Teams willing to experiment with upcoming checks. | High; pin the Biome version in CI to prevent unexpected failures. |
Trade-offs
Recommended versus selective
The recommended baseline reduces initial configuration and covers common correctness issues. Selective categories give teams control over noise, for example by enabling correctness while turning off style rules that conflict with existing conventions. The trade-off is maintenance: every selective category list is an explicit contract that must be updated as Biome promotes rules out of nursery.
Local pre-commit versus CI-only
Running biome check --write locally gives developers immediate feedback and auto-fixes safe issues before a commit. CI-only enforcement with biome ci avoids local tooling drift but lets violations reach the pull request. A practical combination is local auto-fix on branches plus a CI gate that fails the build on remaining violations.
Formatter limits
Biome's formatter is intentionally opinionated and exposes fewer formatting knobs than Prettier. This ends formatting debates but removes fine-grained style control. Biome also does not support custom ESLint plugins or type-aware TypeScript rules, so projects relying on those checks cannot fully replace ESLint without code or tooling changes.
Implementation: configure and validate
1. Install and initialize Biome
Run from the project root:
cd
npm install --save-dev @biomejs/biome
npx biome init
Required permissions: read and write access to the project directory. No elevated privileges are needed.
Expected check: biome --version prints the installed CLI version. Confirm it matches the version pinned in your package manager or CI container.
2. Configure biome.jsonc
{
"organizeImports": { "enabled": true },
"linter": {
"rules": {
"recommended": true
}
},
"formatter": {
"enabled": true
}
}
This enables import organization, the recommended lint baseline, and the formatter. Because the file is JSONC, comments are allowed, but scripts that consume it must use a JSONC-compatible parser.
3. Check a sample file
npx biome check src/example.ts
An exit code of zero means no violations. A non-zero exit means Biome found diagnostics and prints them to standard output. Do not assume a specific error message; inspect the actual output in your environment.
4. Apply safe auto-fixes on a branch
git checkout -b biome-fixes
npx biome check --write src/
git diff --stat
--write changes files in place. On a large legacy codebase this can rewrite many files at once. Review the resulting diff before merging. Rollback: revert the working tree with git checkout -- src/ or abandon the branch.
5. Gate merges in CI
npx biome ci
biome ci runs the formatter and linter without modifying files and exits non-zero on violations. Add this command to your pipeline after dependencies are installed. Verification: introduce an intentional lint violation on a scratch branch and confirm the CI job fails and blocks the build.
Limitations
- No custom ESLint plugins.
- No type-aware TypeScript rules, which require type information at lint time.
- Nursery rules are unstable and can change between releases.
- JSONC is not valid plain JSON.
Practical verification
- Run
biome --versionand compare it to the pinned dependency. - Run
biome checkon a small sample file and confirm the exit code. - Run
biome check --writeon a scratch copy and inspect the file diff. - Add
biome cito CI and confirm a deliberate violation produces a non-zero exit.
Rollback
Only biome check --write mutates the repository. If the auto-fix output is unacceptable, revert the affected files or reset the feature branch before merging. CI-only invocation with biome ci does not change files and therefore needs no file-level rollback.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.