Up to 100x faster on circular dependency detection. Reproducible benchmarks. Full methodology.
π Drop-in replacement β 100% compatible with all
eslint-plugin-importrules, but faster, LLM-optimized error messages, and fewer false positives/negatives.
TL;DR
| Benchmark | 1K Files | 5K Files | 10K Files |
|---|---|---|---|
| Core Rules (9) | 1.6x | 3.3x | 5.2x |
| Recommended Preset | 1.4x | 3.0x | 5.5x |
| no-cycle Only | 25.7x | 54.9x | ~100x* |
*10K projection based on O(nΒ²) scaling pattern observed at 1Kβ5K. We stopped at 5K because eslint-plugin-import would take 10+ minutes.
Why eslint-plugin-import is Slow
The original eslint-plugin-import uses an O(nΒ²) module resolution algorithm:
- For each file, parse all imports
- For each import, resolve the full module path
-
For
no-cycle, traverse the entire dependency graph for every file
This creates quadratic complexity. On 5,000 files with interconnected imports, the no-cycle rule alone takes 148 seconds.
How eslint-plugin-import-next Fixes This
We rewrote the core algorithms:
- Cached module resolution β resolve each path once, cache permanently
- Incremental graph building β build the dependency graph incrementally, not per-file
- Cycle detection with Tarjan's algorithm β O(n) instead of O(nΒ²)
Result: 2.71 seconds for the same 5,000 files.
Benchmark 1: Core Rules (9 rules)
Both plugins configured with identical rules:
-
no-unresolved,named,namespace,default,export -
no-named-as-default,no-named-as-default-member,no-duplicates,order
| Files | eslint-plugin-import | eslint-plugin-import-next | Speedup |
|---|---|---|---|
| 1,000 | 2.80s | 1.78s | 1.6x |
| 5,000 | 19.04s | 5.76s | 3.3x |
| 10,000 | 58.67s | 11.26s | 5.2x |
Takeaway: Even with basic rules, the performance gap grows with codebase size.
Benchmark 2: Recommended Preset
Using the full recommended configuration from each plugin.
| Files | eslint-plugin-import | eslint-plugin-import-next | Speedup |
|---|---|---|---|
| 1,000 | 2.42s | 1.78s | 1.4x |
| 5,000 | 18.43s | 6.07s | 3.0x |
| 10,000 | 57.74s | 10.57s | 5.5x |
Takeaway: Recommended presets show similar scaling β 5.5x faster at 10K files.
Benchmark 3: no-cycle Rule Only
This is where the difference is massive. The no-cycle rule detects circular dependencies.
| Files | eslint-plugin-import | eslint-plugin-import-next | Speedup |
|---|---|---|---|
| 1,000 | 27.03s | 1.05s | 25.7x |
| 5,000 | 148.59s | 2.71s | 54.9x |
| 10,000 | ~600s (projected)* | ~5s (projected) | ~100x |
*10K Projection Note: Based on the O(nΒ²) scaling observed from 1Kβ5K (27sβ148s = 5.5x increase for 5x files), we project eslint-plugin-import would take ~10 minutes at 10K files. We didn't run this because waiting 10+ minutes per iteration is impractical. eslint-plugin-import-next scales linearly (O(n)), so ~5s is expected.
Takeaway: If you use no-cycle (and you should), the speedup is 25-100x depending on codebase size.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β no-cycle Rule: 5,000 files β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β eslint-plugin-import: 148.59s βββββββββββββββββββββββββββββ
β eslint-plugin-import-next: 2.71s β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Why no-cycle is Critical
Circular dependencies cause:
- Build failures with tree-shaking
- Runtime bugs with undefined imports
- Memory leaks in bundlers
- Test flakiness from initialization order
Most teams disable no-cycle because it's too slow. With eslint-plugin-import-next, you can finally enable it.
Methodology
Apple-to-apple comparison β full source code
| Spec | Details |
|---|---|
| Codebase sizes | 1,000 / 5,000 / 10,000 JavaScript files |
| Iterations | 3-5 runs per size, per plugin |
| Fixtures | Realistic JS files with named/default imports, barrel files, cross-file dependencies |
| Environment | Node v20.19.5, Apple Silicon M1 (arm64), ESLint v9.17.0 |
| Cache | Cleared between each run |
Run It Yourself
git clone https://github.com/ofri-peretz/eslint-benchmark-suite.git
cd eslint-benchmark-suite
npm install
npm run generate:import
npm run benchmark:import
npm run benchmark:import-recommended
npm run benchmark:import-no-cycle
Migration Takes 2 Minutes
# Remove old plugin
npm uninstall eslint-plugin-import
# Install new plugin
npm install --save-dev eslint-plugin-import-next
// eslint.config.js
import importNext from 'eslint-plugin-import-next';
export default [importNext.configs.recommended];
Resources
π¦ npm: eslint-plugin-import-next
π Benchmark Suite
π Full Rule List
π Are you still waiting 45+ seconds for ESLint? Try import-next and share your results!
For more updates, follow me on:
Copyright (c) 2025 Ofri Peretz. All rights reserved.
Top comments (0)