Benchmarks Code quality
ESLint vs Biome
Four equivalent rule classes over nearly 100,000 lines of JavaScript.
Products compared
Tests
Test 1 Time per pass
20 measured passes over the corpus. Box is the middle half of the runs, line is the median, whiskers reach the fastest and slowest pass, dots are every run. (LOWER ms = FASTER)
All 20 samples as a table
| Run | ESLint | Biome |
|---|---|---|
| 1 | 108.8 ms | 75.1 ms |
| 2 | 105.9 ms | 74.0 ms |
| 3 | 107.2 ms | 73.6 ms |
| 4 | 107.5 ms | 72.1 ms |
| 5 | 105.2 ms | 75.3 ms |
| 6 | 105.5 ms | 78.7 ms |
| 7 | 105.2 ms | 79.6 ms |
| 8 | 104.6 ms | 78.5 ms |
| 9 | 104.2 ms | 79.4 ms |
| 10 | 108.9 ms | 76.3 ms |
| 11 | 108.7 ms | 77.8 ms |
| 12 | 103.5 ms | 76.2 ms |
| 13 | 104.9 ms | 74.6 ms |
| 14 | 106.4 ms | 75.4 ms |
| 15 | 106.9 ms | 72.8 ms |
| 16 | 105.4 ms | 75.6 ms |
| 17 | 105.9 ms | 74.8 ms |
| 18 | 105.6 ms | 72.5 ms |
| 19 | 105.6 ms | 75.1 ms |
| 20 | 104.8 ms | 71.5 ms |
Full report, as hyperfine prints it
Benchmark 1: ESLint 9.34.0
- Time (mean ± σ)
- 106.0 ms ± 1.5 ms
- Range (min … max)
- 103.5 ms … 108.9 ms
- Median
- 105.6 ms 20 runs
Benchmark 2: Biome 2.2.2fastest
- Time (mean ± σ)
- 75.4 ms ± 2.4 ms
- Range (min … max)
- 71.5 ms … 79.6 ms
- Median
- 75.2 ms 20 runs
Matched rule intent
Each row is one intent both tools enforce. The implementations differ; the intent is what was held equal.
| Intent | ESLint | Biome |
|---|---|---|
| Unused variables | no-unused-vars | correctness/noUnusedVariables |
| Strict equality | eqeqeq | suspicious/noDoubleEquals |
| Debugger statements | no-debugger | suspicious/noDebugger |
| Prefer const | prefer-const | style/useConst |
Test conditions: rig, corpus, protocol
- Machine
- MacBook Pro
- Chip
- Apple M2 Max
- Cores
- 12 CPU cores
- Memory
- 96 GB
- OS
- macOS 26.5.2 (arm64)
- Runtime
- Bun 1.4.0
Rig
- Name
- ESLint 9.34.0 library source
- Source
node_modules/eslint/lib/**/*.js- Files
- 391
- Lines
- 99,880
- Size
- 2.73 MB
Corpus
- Warmups
- 3 unmeasured passes
- Measured
- 20 passes per tool
- Process
- A new CLI process for every measured pass
- Cache
- Warm filesystem cache after three unmeasured passes
- Output
- Diagnostics produced and redirected away from the terminal
Protocol
What did we learn?
Biome finished 1.4x faster. Biome took 75.2 ms at the median. ESLint took 105.6 ms on the same warmed corpus.
What this does not prove
- This isolates lint throughput. It does not score rule coverage, editor integrations, migration cost, or ecosystem compatibility.
- The paired rules express the same intent, but their implementations and exact diagnostics are not identical.
- The corpus is ESLint's own JavaScript source and may not represent a typical application repository.
Rerun it yourself: the runner and this corpus definition are in the repository, and the methodology page covers what every run holds constant. Think a result is wrong? Open an issue with your rig and your samples.