[Skip to main content](https://www.pkgpulse.com/blog/biome-vs-eslint-prettier-linting-2026#main-content) ## [TL;DR](https://www.pkgpulse.com/blog/biome-vs-eslint-prettier-linting-2026\#tldr) **Biome is production-ready for most JavaScript and TypeScript projects, but ESLint + Prettier is still the right call if you need the full ESLint plugin ecosystem.** Biome's 25x speed advantage is real and meaningful in CI. The formatter is nearly identical to Prettier. The linter covers ~80% of common ESLint rules. What Biome can't replace yet: type-aware lint rules (requires TypeScript language service), framework-specific plugins (eslint-plugin-react-hooks, eslint-plugin-next), and any custom ESLint rules your team has written. Verdict: new projects → Biome. Existing projects with heavy plugin usage → evaluate the gap before switching. ## [Key Takeaways](https://www.pkgpulse.com/blog/biome-vs-eslint-prettier-linting-2026\#key-takeaways) - **Speed**: Biome formats and lints in ~50ms; ESLint + Prettier takes ~2-3s for same project - **Coverage**: ~250 lint rules (growing); ESLint has 1000+ with the plugin ecosystem - **Prettier compatibility**: Biome's formatter matches Prettier output for ~96% of cases - **Not yet in Biome**: type-aware rules, React Hooks rules, Next.js plugin, custom rule authoring (in roadmap) - **Configuration**: one config file (`biome.json`) vs two separate configs * * * ## [Speed: The Main Reason to Switch](https://www.pkgpulse.com/blog/biome-vs-eslint-prettier-linting-2026\#speed-the-main-reason-to-switch) ```bash # Real benchmark — a Next.js project with ~150 TypeScript files: # ESLint + Prettier (separate runs): npx eslint . --ext .ts,.tsx → 3.2 seconds npx prettier --check "**/*.{ts,tsx}" → 1.1 seconds Total: ~4.3 seconds # Biome (lint + format together): npx biome check . → 0.18 seconds # 24x faster combined # CI impact (running on every PR): # ESLint + Prettier: 4-5 seconds of your CI job # Biome: ~0.2 seconds # Pre-commit hooks (runs on staged files): # ESLint + Prettier (lint-staged): ~1.5s per commit # Biome: ~0.05s per commit # Developer experience: the difference between "imperceptible" and "I notice this every time" # Why Biome is faster: # → Rust implementation (not Node.js) # → Parallel processing of files # → Single pass: lint + format in one traversal # → No plugin loading overhead (rules are compiled in) ``` * * * ## [Setup: One Config vs Two Configs](https://www.pkgpulse.com/blog/biome-vs-eslint-prettier-linting-2026\#setup-one-config-vs-two-configs) ```json // Biome — biome.json (one file for everything): { "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json", "organizeImports": { "enabled": true }, "linter": { "enabled": true, "rules": { "recommended": true, "correctness": { "noUnusedVariables": "error" }, "style": { "noParameterAssign": "warn" }, "nursery": { "useSortedClasses": "warn" } } }, "formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2, "lineWidth": 100 }, "javascript": { "formatter": { "quoteStyle": "double", "trailingCommas": "all", "semicolons": "always" } }, "files": { "ignore": ["node_modules", "dist", ".next"] } } // Compare to ESLint + Prettier: // .eslintrc.json OR eslint.config.mjs (ESLint 9 flat config) // .prettierrc // .prettierignore // .eslintignore // package.json scripts to run both // lint-staged config for pre-commit hooks // Biome replaces all of that with one file. ``` * * * ## [Lint Rules Coverage](https://www.pkgpulse.com/blog/biome-vs-eslint-prettier-linting-2026\#lint-rules-coverage) ``` Biome rules (v1.9, 2026) — grouped by ESLint equivalent: ✅ Covered well: → no-unused-vars, no-undef → biome: correctness/noUnusedVariables → no-console → biome: suspicious/noConsole → eqeqeq → biome: suspicious/noDoubleEquals → no-var → biome: style/noVar → prefer-const → biome: style/useConst → no-empty → biome: correctness/noEmptyBlockStatements → no-duplicate-imports → biome: correctness/noDuplicateObjectKeys → arrow-body-style → biome: style/useArrowFunction → object-shorthand → biome: style/useShorthandAssign → 200+ more rules... ⚠️ Partially covered / different API: → import/order → biome: organizeImports (reorders, doesn't configure) → jsx-a11y/* → basic accessibility rules, not all of jsx-a11y ❌ Not yet in Biome: → Type-aware rules (requires TypeScript type checker) → @typescript-eslint/no-floating-promises → @typescript-eslint/no-misused-promises → @typescript-eslint/consistent-return (typed) → eslint-plugin-react-hooks (useEffect deps, hooks rules) → eslint-plugin-next (app router patterns, image optimization rules) → eslint-plugin-import/no-cycle (circular dependency detection) → Custom rules your team wrote The gap is real but smaller than it was. Most "critical" lint rules are covered. The missing ones are important for React/Next.js specifically. ``` * * * ## [Prettier Compatibility: How Close Is It?](https://www.pkgpulse.com/blog/biome-vs-eslint-prettier-linting-2026\#prettier-compatibility-how-close-is-it) ```javascript // Biome's formatter is designed to match Prettier's output // Real-world compatibility: ~96% identical for JS/TS // Cases where they differ (edge cases): // 1. Long template literals const query = `SELECT * FROM users WHERE id = ${userId} AND status = 'active' AND created_at > '2024-01-01'`; // Prettier: keeps on one line if fits, wraps differently // Biome: similar but not identical on complex expressions // 2. Decorators (TypeScript) // Some class decorator formatting differs slightly // 3. Complex JSX expressions // Multi-line JSX attributes format slightly differently in edge cases // For the vast majority of code: identical output. // The 4% difference is in edge cases you'll rarely hit. // Migration from Prettier: # Run Biome formatter on your entire codebase once: npx biome format --write . # Check what changed (should be minimal): git diff # If there are many meaningful diffs, the code was inconsistently formatted. # Biome will now be the source of truth. # Teams commonly report: # → 0-20 files changed on a typical codebase # → Changes are whitespace/trailing comma in edge cases # → No semantic code changes ``` * * * ## [Integration with Editors and CI](https://www.pkgpulse.com/blog/biome-vs-eslint-prettier-linting-2026\#integration-with-editors-and-ci) ```bash # VS Code — install the Biome extension: # Extensions: "Biome" (biomejs.biome) # settings.json: { "editor.defaultFormatter": "biomejs.biome", "editor.formatOnSave": true, "[javascript]": { "editor.defaultFormatter": "biomejs.biome" }, "[typescript]": { "editor.defaultFormatter": "biomejs.biome" }, "[typescriptreact]": { "editor.defaultFormatter": "biomejs.biome" } } # The extension works well — fast, accurate # Pre-commit hooks (replace lint-staged + eslint/prettier): # package.json: { "scripts": { "prepare": "simple-git-hooks" }, "simple-git-hooks": { "pre-commit": "npx lint-staged" }, "lint-staged": { "*.{js,ts,jsx,tsx,json,css}": "biome check --apply --no-errors-on-unmatched" } } # CI (GitHub Actions): - name: Lint and Format Check run: npx biome ci . # biome ci = check without --write; exits non-zero if issues found # Replaces separate eslint and prettier --check steps # The biome ci command is designed exactly for this use case. ``` * * * ## [Migration from ESLint + Prettier](https://www.pkgpulse.com/blog/biome-vs-eslint-prettier-linting-2026\#migration-from-eslint--prettier) ```bash # Step 1: Initialize Biome npm install --save-dev --save-exact @biomejs/biome # Step 2: Generate config from existing ESLint config npx biome migrate eslint --include-inspired # --include-inspired: adds Biome rules "inspired by" your ESLint rules # Step 3: Format with Biome once (commit this separately for clean history) npx biome format --write . git add -A && git commit -m "chore: migrate formatter to Biome" # Step 4: Fix linting issues npx biome check --apply . # Some will be auto-fixed. Others need manual attention. # Step 5: Find the ESLint rules you'll miss # Go through your .eslintrc and categorize: # → Rule covered by Biome? → Remove from ESLint # → Rule is react-hooks or type-aware? → Keep ESLint for JUST those rules # Step 6: The hybrid approach (if you need react-hooks rules): # Keep ESLint for only what Biome doesn't cover: # .eslintrc: { "plugins": ["react-hooks"], "rules": { "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn" // Nothing else — Biome handles the rest } } # This is the recommended migration path for React projects. # Use Biome for formatting + most linting. # Keep a minimal ESLint config for react-hooks only. ``` * * * ## [Verdict: Should You Switch?](https://www.pkgpulse.com/blog/biome-vs-eslint-prettier-linting-2026\#verdict-should-you-switch) ``` New greenfield project (2026): → Yes — use Biome from day one → Add minimal ESLint config for react-hooks if it's a React project → The speed win in CI is real; the single config is a DX improvement → The rule gap doesn't matter if you're starting fresh Existing project (small, no complex ESLint plugins): → Yes — migrate. 2-4 hour job. Net positive. → Use the migrate command; review diffs; ship it Existing project (React/Next.js, heavy plugin usage): → Hybrid approach — Biome for format + most lint, ESLint for react-hooks + next → Not "switch" but "add Biome alongside a reduced ESLint config" → You still get the speed benefit for most of the work Existing project (custom ESLint rules, type-aware rules critical): → Not yet — monitor Biome's type-aware rule roadmap → Expected in late 2026 based on their public roadmap → Reevaluate in 6 months The trajectory is clear: Biome is getting better fast. The rule gap that seemed large in 2024 is substantially smaller in 2026. Type-aware rules are the final frontier. ``` * * * _Compare Biome, ESLint, and Prettier download trends at [PkgPulse](https://www.pkgpulse.com/)._ See the live comparison [View biome vs. eslint on PkgPulse →](https://www.pkgpulse.com/compare/biome-vs-eslint) ## Comments ### The 2026 JavaScript Stack Cheatsheet One PDF: the best package for every category (ORMs, bundlers, auth, testing, state management). Used by 500+ devs. Free, updated monthly. Get the Free Cheatsheet