CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-eslint-plugin-unused-imports

ESLint plugin that identifies and automatically removes unused ES6 module imports

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

ESLint Plugin Unused Imports

ESLint Plugin Unused Imports identifies and automatically removes unused ES6 module imports from JavaScript and TypeScript codebases. It extends the standard no-unused-vars rule to specifically handle import statements in the Abstract Syntax Tree (AST), providing autofix capabilities to clean up unnecessary imports.

Package Information

  • Package Name: eslint-plugin-unused-imports
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install eslint-plugin-unused-imports --save-dev

Core Imports

import unusedImports from "eslint-plugin-unused-imports";

For CommonJS:

const unusedImports = require("eslint-plugin-unused-imports");

Basic Usage

import unusedImports from "eslint-plugin-unused-imports";

export default [{
    plugins: {
        "unused-imports": unusedImports,
    },
    rules: {
        "no-unused-vars": "off", // or "@typescript-eslint/no-unused-vars": "off",
        "unused-imports/no-unused-imports": "error",
        "unused-imports/no-unused-vars": [
            "warn",
            {
                "vars": "all",
                "varsIgnorePattern": "^_",
                "args": "after-used",
                "argsIgnorePattern": "^_",
            },
        ]
    }
}];

Architecture

The plugin uses a composable architecture built around several key components:

  • Plugin Structure: ESLint.Plugin object containing metadata and rule definitions
  • Rule Composition: Base rules are dynamically loaded and enhanced with predicates
  • Predicate System: Filter and transformation functions that modify rule behavior based on AST node types
  • Base Rule Loading: Smart detection system that chooses appropriate no-unused-vars implementation
  • Autofix Engine: Sophisticated AST-based fixing logic for various import scenarios

Capabilities

Plugin Export

Main ESLint plugin export containing the two rules.

interface ESLintPlugin {
  meta: {
    name: string;
  };
  rules: {
    "no-unused-vars": Rule.RuleModule;
    "no-unused-imports": Rule.RuleModule;
  };
}

const plugin: ESLintPlugin;
export default plugin;

No Unused Imports Rule

Detects and autofixes unused import statements with comprehensive autofix support.

/**
 * ESLint rule that identifies unused import statements and provides autofix
 * Handles various import scenarios including single imports, multiple imports, 
 * default + named combinations, and proper formatting preservation
 */
const noUnusedImportsRule: Rule.RuleModule;

Rule Configuration:

  • Use "unused-imports/no-unused-imports": "error" to enable with autofix
  • No additional options - inherits from base no-unused-vars configuration

Autofix Examples:

// Single unused import - entire statement removed
import { unused } from 'module';  // ❌ Removed completely

// Multiple imports with some unused - only unused ones removed
import { used, unused1, unused2 } from 'module';
// ⬇️ Becomes:
import { used } from 'module';

// Default + named imports with unused named import
import React, { useState, unused } from 'react';
// ⬇️ Becomes:
import React, { useState } from 'react';

// All imports unused - entire statement removed with proper newline handling
import { unused1, unused2 } from 'module';
console.log('next line');
// ⬇️ Becomes:
console.log('next line');  // Proper spacing preserved

No Unused Vars Rule

Enhanced version of standard no-unused-vars rule that excludes imports to prevent duplicate reporting.

/**
 * Enhanced no-unused-vars rule that filters out import-related problems
 * Prevents duplicate reporting when used with no-unused-imports rule
 * Supports all standard no-unused-vars configuration options
 */
const noUnusedVarsRule: Rule.RuleModule;

Rule Composition System

Core system for creating filtered rules with predicate-based problem filtering.

/**
 * Predicate function type for filtering rule problems
 * Returns the problem to report or false to suppress it
 */
type Predicate = (
  problem: Rule.ReportDescriptor,
  context: Rule.RuleContext,
) => Rule.ReportDescriptor | false;

/**
 * Creates a new rule by applying a predicate filter to a base rule
 * Used to create both no-unused-imports and no-unused-vars rules
 */
function createRuleWithPredicate(
  name: string,
  baseRule: Rule.RuleModule,
  predicate: Predicate,
): Rule.RuleModule;

/**
 * Predicate that filters for unused import statements (includes autofix)
 */
const unusedImportsPredicate: Predicate;

/**
 * Predicate that filters out import statements (excludes imports)
 */
const unusedVarsPredicate: Predicate;

Predicate System Example:

// How predicates filter problems from the base no-unused-vars rule
const problem = {
  node: someASTNode,
  message: "someVariable is defined but never used",
  // ... other problem properties
};

// unusedImportsPredicate: Returns problem ONLY if it's an import
// - Checks if problem.node.parent matches /^Import(|Default|Namespace)Specifier$/
// - If import: adds autofix logic and returns enhanced problem
// - If not import: returns false (suppresses the problem)

// unusedVarsPredicate: Returns problem ONLY if it's NOT an import  
// - Checks if problem.node.parent matches /^Import(|Default|Namespace)Specifier$/
// - If import: returns false (suppresses the problem)
// - If not import: returns problem unchanged

Base Rule Loading System

Dynamic rule loading system that selects the appropriate no-unused-vars implementation.

/**
 * Gets the appropriate base no-unused-vars rule using fallback strategy:
 * 1. @typescript-eslint/eslint-plugin (if available)
 * 2. typescript-eslint unified plugin (if available) 
 * 3. ESLint core no-unused-vars rule (fallback)
 */
function getBaseRule(): Rule.RuleModule;

/**
 * Attempts to load no-unused-vars from @typescript-eslint/eslint-plugin
 * Returns null if package is not available
 */
function getRuleFromTSLintPlugin(): Rule.RuleModule | null;

/**
 * Attempts to load no-unused-vars from typescript-eslint unified package
 * Returns null if package is not available
 */
function getRuleFromTSLint(): Rule.RuleModule | null;

/**
 * Loads the core ESLint no-unused-vars rule as fallback
 * Always succeeds as ESLint is a required dependency
 */
function getESLintBaseRule(): Rule.RuleModule;

Rule Configuration: Standard ESLint no-unused-vars options:

"unused-imports/no-unused-vars": [
    "warn",
    {
        "vars": "all" | "local",
        "varsIgnorePattern": string, // regex pattern
        "args": "after-used" | "all" | "none",
        "argsIgnorePattern": string, // regex pattern
        "caughtErrors": "none" | "all",
        "caughtErrorsIgnorePattern": string, // regex pattern
        "destructuredArrayIgnorePattern": string, // regex pattern
        "ignoreRestSiblings": boolean
    }
]

Types

/**
 * ESLint Rule Module interface for both plugin rules
 */
interface Rule.RuleModule {
  meta: {
    type?: "problem" | "suggestion" | "layout";
    docs?: {
      description?: string;
      category?: string;
      recommended?: boolean;
      url?: string;
    };
    fixable?: "code" | "whitespace";
    schema: any[];
    messages: Record<string, string>;
  };
  create(context: Rule.RuleContext): Rule.RuleListener;
}

/**
 * ESLint Rule Context provided to rule implementations
 */
interface Rule.RuleContext {
  id: string;
  options: any[];
  settings: any;
  parserPath: string;
  parserOptions: any;
  sourceCode: SourceCode;
  report(descriptor: Rule.ReportDescriptor): void;
}

/**
 * ESLint Report Descriptor for rule violations
 */
interface Rule.ReportDescriptor {
  node?: any;
  loc?: any;
  message: string;
  data?: any;
  fix?: (fixer: Rule.RuleFixer) => Rule.Fix | Rule.Fix[];
}

Dependencies & Compatibility

Peer Dependencies:

  • eslint: ^8.0.0 || ^9.0.0
  • @typescript-eslint/eslint-plugin: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 (optional)

Version Compatibility:

  • Version 4.1.x: ESLint 9 with @typescript-eslint/eslint-plugin 5-8
  • Version 4.0.x: ESLint 9 with @typescript-eslint/eslint-plugin 8
  • Version 3.x.x: ESLint 8 with @typescript-eslint/eslint-plugin 6-7
  • Version 2.x.x: ESLint 8 with @typescript-eslint/eslint-plugin 5
  • Version 1.x.x: ESLint 6 and 7

Framework Integration:

  • React: Requires eslint-plugin-react with react/jsx-uses-react and react/jsx-uses-vars rules enabled
  • TypeScript: Requires @typescript-eslint/eslint-plugin and @typescript-eslint/parser for TypeScript projects
  • Flat Config: Works with ESLint 9+ flat configuration format
  • Legacy Config: Compatible with .eslintrc format for older ESLint versions

docs

index.md

tile.json