DEV Community

Cover image for Why eslint-plugin-import Takes 45 Seconds (And How We Fixed It)
Ofri Peretz
Ofri Peretz

Posted on

Why eslint-plugin-import Takes 45 Seconds (And How We Fixed It)

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  ▏                  │
└─────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

2. The no-cycle Problem

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
// eslint.config.js
import importNext from 'eslint-plugin-import-next';

export default [importNext.configs.recommended];
Enter fullscreen mode Exit fullscreen mode

That's it. Same rules, 100x faster.

Benchmark It Yourself

⭐ Star on GitHub and Run the Benchmark

# Compare on your own codebase
time npx eslint --no-cache . # With eslint-plugin-import
time npx eslint --no-cache . # With eslint-plugin-import-next
Enter fullscreen mode Exit fullscreen mode

📦 npm: eslint-plugin-import-next
📖 Migration Guide


🚀 Is your CI slow? Drop a comment with your lint times!

Follow for more performance deep-dives:
GitHub | LinkedIn

Top comments (0)