How-ToFebruary 13, 20254 min read

How to Find and Remove Unused Imports in JavaScript and TypeScript

Unused imports bloat your bundle and clutter your code. Learn how to detect and remove them using ESLint, ts-prune, and automated tools.

unused-importsjavascripttypescripteslintbundle-size

Unused imports are one of the most common forms of dead code in JavaScript and TypeScript projects. They accumulate silently as you refactor, move functions between files, and delete features. Each unused import adds noise to your code and can increase your production bundle size.

This guide covers three approaches to finding and removing them: ESLint rules, ts-prune, and automated scanning.

Why Unused Imports Matter

Every import statement tells your bundler to include that module in the dependency graph. While modern bundlers like Webpack, Rollup, and esbuild support tree-shaking, it does not always work:

  • Barrel files (index.ts that re-exports everything) often defeat tree-shaking because the bundler cannot determine which re-exports have side effects
  • CommonJS imports (require()) are not statically analyzable, so bundlers include the entire module
  • Side-effect imports (import "./polyfill") must always be included, even if nothing is imported by name

The result: unused imports that you think are harmless may actually ship to production.

Method 1: ESLint Rules

The fastest way to catch unused imports is with ESLint. Two rules handle this:

no-unused-vars

TypeScript ESLint's @typescript-eslint/no-unused-vars catches imported values that are never referenced:

{
  "rules": {
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        "argsIgnorePattern": "^_",
        "varsIgnorePattern": "^_"
      }
    ]
  }
}

This flags any import that is not used in the file. The _ prefix pattern lets you intentionally mark variables as unused (common for destructured parameters you do not need).

Auto-fix with ESLint

Run ESLint with the --fix flag to automatically remove unused imports:

npx eslint --fix "src/**/*.{ts,tsx}"

Limitation: ESLint works per-file. It cannot tell you if an exported function is unused across your entire project -- only if an import is unused within the file that imports it.

Method 2: ts-prune for Project-Wide Detection

ts-prune analyzes your entire TypeScript project and reports exports that are never imported anywhere:

npx ts-prune

Output looks like:

src/utils/formatCurrency.ts:3 - formatCurrency
src/helpers/legacy.ts:1 - calculateDiscount
src/components/OldButton.tsx:5 - OldButton

Each line shows a file, line number, and the unused export name. If every export in a file is unused, the entire file is dead code.

Limitation: ts-prune only detects unused exports. It does not detect unused imports within a file (use ESLint for that) or unused local variables.

Method 3: Automated Scanning with CleanAI

CleanAI combines ESLint, ts-prune, and other language-specific tools into a single scan. It runs directly in VS Code or Cursor and presents findings in a visual panel:

  1. Open your project in VS Code or Cursor
  2. Run the "CleanAI: Analyze Codebase" command
  3. Review findings grouped by file
  4. Click "Remove" to delete individual findings, or use Auto Clean (Safe) to remove them incrementally with build verification

CleanAI handles the full pipeline: detecting unused imports, unused exports, unused functions, and orphaned files across TypeScript, JavaScript, Swift, and Python projects.

Safe Removal Workflow

Before bulk-removing unused imports, follow this process:

  1. Commit your current work so you have a clean rollback point
  2. Run the detection tool (ESLint, ts-prune, or CleanAI)
  3. Review dynamic imports -- some imports are used via require() or string-based dynamic imports that static analysis cannot detect
  4. Remove in small batches rather than all at once
  5. Run your test suite and build after each batch to catch regressions

Preventing Unused Imports

Add these to your development workflow to prevent unused imports from accumulating:

  • Enable no-unused-vars as an error (not a warning) in your ESLint config
  • Add ESLint to your CI pipeline so unused imports block merges
  • Use your editor's auto-import cleanup -- VS Code can organize imports on save with "editor.codeActionsOnSave": { "source.organizeImports": true }
  • Run periodic project-wide scans to catch unused exports that per-file linting misses

Unused imports are a small problem individually, but they compound across hundreds of files. Catching them early keeps your codebase clean and your bundles lean.