Skip to main content

Migrating from eslint-plugin-import

eslint-plugin-import (and the actively maintained fork eslint-plugin-import-x) provides ESLint rules for the import graph. Several of them have direct rev-dep equivalents that run far faster on the whole graph at once.

Why migrate​

  • Speed. The graph-aware import rules (especially no-cycle and no-unused-modules) are notoriously slow on large repos because ESLint re-resolves per file. rev-dep builds the graph once in Go - faster.
  • Consolidation. One rev-dep config covers cycles, unused exports, unresolved/extraneous dependencies, and path restrictions together.
  • You can keep ESLint. Migrate just the heavy graph rules to rev-dep and leave the rest of your ESLint setup in place.

What carries over, what changes​

  • Covered well: cycles, unused exports, unresolved imports, extraneous/missing dependencies, restricted paths.
  • Different execution model. ESLint reports per file in the editor and on lint; rev-dep is a whole-graph batch check for CI/local runs. You lose inline editor squiggles for these rules but gain speed and cross-package accuracy.

Feature mapping​

eslint-plugin-import rulerev-dep
import/no-cyclecircularImportsDetection
import/no-unused-modulesunusedExportsDetection (+ orphanFilesDetection for files with no used exports)
import/no-unresolvedunresolvedImportsDetection
import/no-extraneous-dependenciesmissingNodeModulesDetection + devDepsUsageOnProdDetection (rev-dep also adds unusedNodeModulesDetection for declared-but-unused packages, which this rule does not detect)
import/no-restricted-pathsrestrictedImportsDetection / moduleBoundaries
import/no-internal-modulesmoduleBoundaries / restrictedImportsDetection
import/no-relative-packagesimportConventions

Translating your config​

ESLint rules like:

// eslint.config.js (flat config)
rules: {
'import/no-cycle': 'error',
'import/no-unused-modules': ['error', { unusedExports: true }],
'import/no-restricted-paths': ['error', {
zones: [{ target: 'src/ui', from: 'src/api' }]
}],
}

become a rev-dep.config.jsonc:

{
"rules": [
{
"path": ".",
"prodEntryPoints": ["src/index.ts"],
"circularImportsDetection": {
"enabled": true
},
"unusedExportsDetection": {
"enabled": true
},
"moduleBoundaries": [
{
"name": "ui-not-from-api",
"pattern": "src/ui/**",
"deny": ["src/api/**"]
}
]
}
]
}

no-restricted-paths zones (target / from) map to either moduleBoundaries (file-pattern to file-pattern) or restrictedImportsDetection (reachability from entry points) - see which to use.

Running it​

# eslint
npx eslint .

# rev-dep
rev-dep config run

Next steps​