PettyUI/.firecrawl/pkgpulse-linting.md
Mats Bosson db906fd85a Fix linting config and package fields
- Replace .eslintrc.cjs with eslint.config.mjs (ESLint 9 flat config)
  using direct eslint-plugin-solid + @typescript-eslint/parser approach
- Add @typescript-eslint/parser to root devDependencies
- Add main/module/types top-level fields to packages/core/package.json
- Add resolve.conditions to packages/core/vite.config.ts
- Create packages/core/tsconfig.test.json for test type-checking
- Remove empty paths:{} from packages/core/tsconfig.json
2026-03-29 02:35:57 +07:00

305 lines
10 KiB
Markdown

[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