Adopting Biome in a TypeScript Project: A Decision Guide
Decide whether to replace ESLint, Prettier, and Webpack with Biome. This guide compares full, partial, and side‑by‑side migrations, explains trade‑offs, and walks through a concrete implementation and validation checklist.
02 Mar 2026, 06:58 UTC

Problem & Takeaway
Teams that maintain large TypeScript codebases often juggle several tooling layers: ESLint for linting, Prettier for formatting, and a bundler like Webpack or Vite for builds. Each adds a dependency, a configuration file, and a CI step. Biome claims to unify formatting, linting, and bundling into a single binary, potentially cutting CI complexity and reducing dependency noise. The decision to migrate hinges on the project’s current tooling, the team’s familiarity with existing rules, and the risk tolerance for breaking changes.
Decision Constraints
- Existing
.eslintrcand.prettierrcconfigurations with many custom rules. - CI pipeline already defined for lint/format steps.
- Team members rely on ESLint plugins (e.g.,
eslint-plugin-react-hooks). - Project size: single repo vs. monorepo with many packages.
- Long‑term maintenance expectations (plugin ecosystem maturity).
Supported Options
When evaluating whether to adopt Biome, consider the following approaches:
- Full Replacement – Remove ESLint, Prettier, and the current bundler; replace with Biome for all three concerns.
- Partial Replacement – Keep ESLint for advanced linting rules but use Biome only for formatting and bundling.
- Side‑by‑Side – Run both toolchains in parallel during a migration window, then phase out the legacy setup.
- No Migration – Continue with the current stack; add Biome only as a supplementary tool for new projects.
Comparison Table
| Aspect | Full Replacement | Partial Replacement | Side‑by‑Side | No Migration |
|---|---|---|---|---|
| Dependency Count | 1 (Biome) | 2 (Biome + ESLint) | 3 (Biome + ESLint + Prettier) | 3 (ESLint + Prettier + Bundler) |
| CI Complexity | 1 step (biome ci) | 2 steps (biome format/lint + eslint) | 3 steps (biome + eslint + prettier) | 3 steps (eslint + prettier + bundler) |
| Rule Coverage | Biome’s built‑in rules (opinionated, limited) | Biome rules + custom ESLint rules | Full rule set during overlap | Full rule set from current stack |
| Build Replacement | Yes (biome bundle) | Yes (biome bundle) | Biomes bundle used in parallel; legacy remains | No (Webpack/Vite) |
| Migration Effort | High – rewrite all rule files, adjust CI | Medium – remove formatting rules, keep lint | Low – incremental diff checks | None |
| Risk of Breaking Changes | High – formatting differences, rule gaps | Medium – formatting differences only | Low – side‑by‑side diff | None |
| Long‑term Maintenance | Low – single binary, fewer updates | Medium – two binaries, plugin updates | Medium – two binaries, but can phase out | High – multiple updates, plugin churn |
Trade‑offs
- Opinionated Defaults – Biome’s default config speeds onboarding but may clash with existing code style. Customization is possible but limited compared to ESLint’s plugin ecosystem.
- Plugin Ecosystem – ESLint offers a vast array of community plugins. Biome’s ecosystem is nascent; missing plugins may force temporary workarounds or rule duplication.
- Performance – Benchmarks show Biome lints and formats >2× faster on large files. For small projects, the difference is negligible, and the learning curve of new CLI commands may outweigh benefits.
- CI Simplification – A single
biome cistep eliminates separate format and lint jobs, reducing pipeline time and maintenance. - Build Tooling – Biome’s bundler covers many typical use‑cases but lacks advanced features (e.g., code splitting, custom loaders) that Webpack or Vite provide. Large monorepos may still require a dedicated bundler.
Concrete Implementation: Full Replacement Example
Below is a step‑by‑step guide for a typical TypeScript project that wants to replace ESLint, Prettier, and Webpack with Biome.
Prerequisites
- Node.js 20+ installed.
- Root project directory
<project-root>. - Git repository with an existing CI configuration.
1. Install Biome
# Global install (optional, for CLI access)
npm install -g biome
# Or use npx for local execution
2. Remove Legacy Tooling
rm -f .eslintrc.js .prettierrc .prettierignore
rm -f webpack.config.js
npm uninstall eslint prettier webpack webpack-cli
Update package.json scripts:
"scripts": {
"dev": "biome run src/ --watch",
"build": "biome bundle src/ --out-dir dist",
"lint": "biome lint src/",
"format": "biome format src/"
}
3. Run Initial Formatting
biome format src/
Review the changes. If you prefer a diff‑only approach, run:
biome format --diff src/
4. Lint the Codebase
biome lint src/
Address any reported issues. Note that Biome’s rule set is narrower; rules you relied on in ESLint may be missing. Investigate equivalent rules or consider retaining ESLint for those specific checks.
5. Bundle for Production
biome bundle src/ --out-dir dist
Verify that the output is correct by running the application or using a simple test script.
6. Update CI Pipeline
Replace separate lint/format jobs with a single biome ci step. Example GitHub Actions job:
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npx biome ci
7. Validate Build
Run the build locally to ensure the output matches expectations:
npm run build
# Check dist/ contents
Validation Checklist
- Formatting Consistency –
biome format --diff src/should produce minimal or no changes compared toprettier --check src/if your code already follows Prettier conventions. - Linting Performance – Measure CPU and wall‑clock times:
time biome lint src/vs.time eslint src/. Expect faster times with Biome for large files. - CI Simplification – Run
npx biome cilocally; it should perform format, lint, and bundle checks in a single command. - Bundle Output – Compare the generated
dist/bundle to the previous Webpack output. Verify that module resolution and asset loading work as expected.
Limitations & Caveats
- Biome’s rule set is currently limited; projects with heavy custom linting may experience missing checks.
- Plugin support is nascent; absence of critical plugins (e.g.,
eslint-plugin-react-hooks) may require manual rule re‑implementation. - Large monorepos may need incremental adoption to avoid breaking existing build scripts.
- Formatting differences can surface during migration; staged or diff‑based migration is recommended.
- IDE integration is available but may conflict with existing ESLint/Prettier plugins; test in your preferred editor before full rollout.
Conclusion
Biomes unified toolchain offers a compelling simplification for teams willing to trade some rule granularity for reduced dependency overhead and faster CI. If your project’s linting needs are modest and you value streamlined tooling, a full replacement can deliver tangible benefits. For teams heavily reliant on ESLint plugins or complex bundling scenarios, a partial or side‑by‑side approach mitigates risk while still reaping some of Biome’s performance advantages.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.