Post-Mortem: Why ESLint Performance Failed (And the 100x Fix)
A technical analysis of performance degradation in large-scale static analysis. The engineering journey from 45s to 0.4s linting times.

Developer velocity dies when CI takes 45 seconds to lint. Here is the technical post-mortem of why traditional linting failed, and how we engineered a 100x speedup into the static analysis ecosystem.
Your CI is slow. Your pre-commit hooks timeout. Developers disable linting to ship faster.
The culprit? eslint-plugin-import.
The Performance Gap
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Linting 10,000 files โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ eslint-plugin-import: 45.0s โโโโโโโโโโโโโโโโโโโโ
โ eslint-plugin-import-next: 0.4s โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
That's 100x faster. Not a typo.
Why Is It So Slow?
1. Cold Module Resolution
// eslint-plugin-import resolves EVERY import from scratch
import { Button } from '@company/ui'; // Resolves entire package
// On every lint run. Every file. Every import.
2. The no-cycle Problem
{% details Click to see why no-cycle is a performance killer %}
The import/no-cycle rule builds a complete dependency graph.
For N files with M imports each:
- Time complexity: O(N ร Mยฒ)
- Memory: Entire graph in RAM
- Result: OOM on large monorepos
# Real GitHub issues:
# "import/no-cycle takes 70% of lint time" (#2182)
# "OOM checking circular dependencies"
# "Minutes to lint a monorepo"
{% enddetails %}
3. No Caching
Every lint run repeats the same work. No incremental analysis.
The Solution
We rebuilt module resolution with:
| Feature | eslint-plugin-import | eslint-plugin-import-next |
|---|---|---|
| Caching | โ None | โ Cross-file shared cache |
| Cycle Detection | O(N ร Mยฒ) | O(N) with memoization |
| TypeScript | ๐ Slow resolver | โก Native TS support |
| Flat Config | โ ๏ธ Partial | โ Native |
Quick Migration
npm uninstall eslint-plugin-import
npm install --save-dev eslint-plugin-import-next
// eslint.config.js
import importNext from 'eslint-plugin-import-next';
export default [importNext.configs.recommended];
That's it. Same rules, 100x faster.
Benchmark It Yourself
# Compare on your own codebase
time npx eslint --no-cache . # With eslint-plugin-import
time npx eslint --no-cache . # With eslint-plugin-import-next
๐ฆ npm: eslint-plugin-import-next ๐ Migration Guide
The Interlace ESLint Ecosystem Interlace is a high-fidelity suite of static code analyzers designed to automate security, performance, and reliability for the modern Node.js stack. With over 330 rules across 18 specialized plugins, it provides 100% coverage for OWASP Top 10, LLM Security, and Database Hardening.
Explore the full Documentation
ยฉ 2026 Ofri Peretz. All rights reserved.
Build Securely. I'm Ofri Peretz, a Security Engineering Leader and the architect of the Interlace Ecosystem. I build static analysis standards that automate security and performance for Node.js fleets at scale.