npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ai-linter

v1.0.6

Published

A linter tool to analyze JavaScript, TypeScript, and Vue code, with a focus on AI-generated code, unused imports, alias resolution, and potential hazards.

Downloads

41

Readme

Advanced Linter for AI-Generated Code

ai-linter is a powerful static analysis tool designed specifically to validate and enhance JavaScript, TypeScript, and Vue code, particularly code generated by AI. It helps ensure code quality, maintainability, and security by identifying potential issues, unused code, and inconsistencies.

Key Features

  • AI-Generated Code Validation: Tailored to scrutinize code produced by AI tools, catching common pitfalls and ensuring adherence to best practices.
  • Unused Import Detection & Cleaning: Identifies and helps remove unused import statements, keeping your codebase clean and optimized.
  • Alias Resolution Verification: Checks and resolves path aliases (e.g., @/components, ~/utils) defined in jsconfig.json, tsconfig.json, Babel, Webpack, Vite, or Next.js configurations, ensuring imports are correctly mapped.
  • Potential Hazard Detection: Flags potentially problematic code constructs such as:
    • eval() usage
    • console.log and other console method calls
    • debugger statements
    • TODO and FIXME comments, prompting for review and action.
  • Import Syntax Error Identification: Detects and reports errors in import statements, including unresolved modules and incorrect named/default imports.
  • Export Validation: Verifies named exports and re-exports, ensuring that what's imported is actually available from the source module.
  • Undeclared Identifier Detection: Finds variables or functions used without prior declaration.
  • Support for Multiple File Types: Analyzes .js, .jsx, .ts, .tsx, and .vue files.
  • Configurable Analysis: Use a .analyzerconfig.json file or command-line options to customize target directories/files, ignored patterns, output format, and more.

Why ai-linter?

As AI-assisted development becomes more prevalent, ensuring the quality and reliability of generated code is crucial. ai-linter provides a focused solution to:

  • Improve Code Quality: By catching errors and bad practices early.
  • Enhance Maintainability: By promoting cleaner, more understandable code.
  • Reduce Bundle Sizes: By helping eliminate unused code.
  • Streamline Code Reviews: By automating the detection of common issues.

Getting Started

Prerequisites

  • Node.js (version 14 or higher recommended)

Installation

Currently, ai-linter can be run directly from its source or integrated as a module.

# Clone the repository (if you haven't already)
git clone <repository-url>
cd ai-linter

# Install dependencies
yarn install # or npm install

Usage

ai-linter offers two primary ways to use its analysis capabilities:

1. Command Line Interface (CLI)

For quick analysis and integration into build scripts, the CLI is the recommended approach. After installation, you might need to make index.js executable or call it via node.

If you've set up the bin field in package.json and installed the package globally or linked it (npm link), you can run:

ai-linter <file|directory> [options]

Otherwise, run from the project root:

node index.js <file|directory> [options]

Examples:

  • Analyze all supported files in the src directory:

    node index.js src/
  • Analyze a specific file:

    node index.js src/components/MyComponent.vue
  • Analyze the current directory, output results in JSON format to report.json:

    node index.js . --format json --output report.json
  • Analyze src but ignore test files:

    node index.js src --ignore "**/*.test.js,**/*.spec.js"

Options:

  • --recursive, -r: Scan subdirectories (default: true, configurable via .analyzerconfig.json).
  • --extensions, -e: File extensions to analyze (default: .js,.jsx,.ts,.tsx,.vue, configurable).
  • --ignore, -i: Glob patterns to ignore (configurable).
  • --format, -f: Output format (json | table | summary) (default: table, configurable).
  • --output, -o: File to write output to (configurable).
  • --help, -h: Display help message.

2. Programmatic Usage (Analyzer Module)

For more complex integrations or custom analysis workflows, you can use the Analyzer module directly in your Node.js projects. The Analyzer constructor accepts an optional cwd (current working directory) parameter. If not provided, it defaults to process.cwd(). This cwd is used as the base for resolving relative paths for configuration files (like jsconfig.json, babel.config.js), analysis target files/directories, and path aliases.

const { Analyzer } = require('ai-linter'); // Or adjust path if used locally

// Example 1: Default behavior (uses process.cwd())
const analyzer1 = new Analyzer();
// Analyzes './src/someFile.js' relative to process.cwd()
const report1 = analyzer1.analyzeFile('./src/someFile.js');
console.log(JSON.stringify(report1, null, 2));

// Example 2: Specifying a custom current working directory
const projectRoot = '/path/to/your/project'; // Replace with actual path
const analyzer2 = new Analyzer(projectRoot);

// Analyze a single file relative to 'projectRoot'
// e.g., resolves to '/path/to/your/project/src/components/MyComponent.js'
const fileReport = analyzer2.analyzeFile('./src/components/MyComponent.js');
console.log(JSON.stringify(fileReport, null, 2));
/* Example fileReport output:
{
  "file": "/path/to/your/project/src/components/MyComponent.js",
  "status": "ok", // or "error", "warning"
  "syntaxError": null, // or { message: "...", line: X, column: Y }
  "imports": [
    {
      "path": "react",
      "specifiers": [{ "name": "default", "alias": "React", "type": "ImportDefaultSpecifier" }],
      "line": 1,
      "resolvedPath": "react", // Path to the module in node_modules or core module name
      "status": "resolved",
      "isExternal": true
    }
  ],
  "dynamicImports": [],
  "exports": [
    { "type": "default", "line": 5 }
  ],
  "unusedImports": [], // e.g., ["unusedIdentifier"]
  "issues": [] // e.g., [{ "type": "console-usage", "message": "Usage of 'console.log'.", "line": 10 }]
}
*/

// Analyze a directory relative to 'projectRoot'
// e.g., analyzes files within '/path/to/your/project/src'
const directoryReport = analyzer2.analyzeDirectory('./src', {
  recursive: true,
  extensions: ['.js', '.ts'],
  ignore: ['node_modules/**'] // Paths in ignore are also relative to the analyzer's cwd or absolute
});
console.log(JSON.stringify(directoryReport, null, 2));
/* Example directoryReport output:
{
  "totalFiles": 5,
  "filesWithErrors": 1,
  "filesWithWarnings": 0,
  "totalImports": 12,
  "unresolvedImports": 1,
  "unusedImports": 2,
  "totalUndeclaredIdentifiers": 0,
  "details": [
    // Array of fileReport objects, one for each analyzed file
    {
      "file": "/path/to/your/project/src/file1.js",
      "status": "ok",
      // ... other properties as in fileReport ...
    },
    {
      "file": "/path/to/your/project/src/fileWithError.js",
      "status": "error",
      "syntaxError": { "message": "Unexpected token", "line": 3, "column": 10 },
      // ... other properties ...
    }
    // ... more file reports ...
  ]
}
*/

This approach gives you direct access to the analysis results as JavaScript objects, allowing for deeper integration with other tools or custom reporting mechanisms.

Configuration File

You can configure ai-linter using a .analyzerconfig.json file in your project root (or the current working directory from which the tool is run):

{
  "target": "src",
  "recursive": true,
  "extensions": [".js", ".jsx", ".ts", ".tsx", ".vue"],
  "ignore": [
    "node_modules/**",
    "dist/**",
    "**/*.test.js"
  ],
  "format": "summary",
  "output": "analysis-report.txt"
}

Command-line arguments will override settings in the configuration file when using the CLI. The target and output paths in the configuration file are resolved relative to the location of the configuration file itself (which is typically the project root or cwd).

How It Works

ai-linter parses your code into an Abstract Syntax Tree (AST) using Babel parser. It then traverses this tree to:

  1. Identify Imports & Exports: Collects all import and export statements.
  2. Resolve Aliases: Uses configurations from common tools (jsconfig.json, tsconfig.json, Webpack, Vite, etc.)—searched relative to the current working directory (or the cwd provided to the Analyzer instance)—to map aliased paths to their actual file locations.
  3. Validate Imports: Checks if imported modules exist and if named/default imports are correctly specified based on the exports of the source file.
  4. Detect Unused Imports: Compares imported identifiers against their usage within the file.
  5. Scan for Code Issues: Looks for patterns like eval(), console.*, debugger, TODO/FIXME comments, undeclared variables, and duplicate object keys.

Detected Issue Types and Examples

ai-linter can detect a variety of issues in your codebase. Here's a list of common issue types, their meanings, and examples of code that would trigger them.

Import/Export Issues

  1. unresolved-import

    • Description: The linter could not find or resolve the module specified in an import statement.
    • Example:
      import something from './non-existent-module';
  2. error-in-imported-file

    • Description: An imported file contains a syntax error, preventing it from being parsed.
    • Example:
      // main.js
      import config from './broken-config';
      
      // broken-config.js
      export default {
        setting: true // Missing semicolon or comma, causing syntax error
      }
  3. unresolved-named-import

    • Description: A named import (e.g., import { specificThing } from 'module';) could not be found among the exports of the target module.
    • Example:
      // utils.js
      export const helper = () => {};
      
      // main.js
      import { nonExistentHelper } from './utils'; // 'nonExistentHelper' is not exported
  4. unresolved-default-import

    • Description: A default import (e.g., import myModule from 'module';) was used, but the target module does not have a default export.
    • Example:
      // config.js
      export const setting = true; // No default export
      
      // main.js
      import appConfig from './config'; // './config' has no default export
  5. unresolved-dynamic-import

    • Description: The linter could not find or resolve the module specified in a dynamic import() call.
    • Example:
      async function loadFeature() {
        const feature = await import('./non-existent-feature');
        // ...
      }
  6. unresolved-re-export-source

    • Description: The source module specified in a re-export statement (e.g., export { name } from './source';) could not be found.
    • Example:
      // index.js
      export { utility } from './missing-utils'; // './missing-utils' does not exist
  7. error-in-re-exported-file

    • Description: A file being re-exported from contains a syntax error.
    • Example:
      // index.js
      export { configValue } from './broken-module';
      
      // broken-module.js
      export const configValue = "test" // Syntax error here
  8. missing-re-exported-name

    • Description: A named entity being re-exported (e.g., export { specificName } from './source';) is not actually exported by the source module.
    • Example:
      // source.js
      export const oneThing = 1;
      
      // index.js
      export { anotherThing } from './source'; // 'anotherThing' is not in 'source.js'
  9. unresolved-re-export-all-source

    • Description: The source module in an export * from './source'; statement could not be found.
    • Example:
      // aggregator.js
      export * from './non-existent-lib';
  10. error-in-re-exported-all-source

    • Description: The source module in an export * from './source'; statement contains a syntax error.
    • Example:
      // aggregator.js
      export * from './faulty-lib';
      
      // faulty-lib.js
      export const item = 1 // Syntax error
  11. unused-imports

    • Description: An imported module or identifier is not used anywhere in the file.
    • Example:
      import { usefulFunction, unusedFunction } from './lib';
      usefulFunction();
      // 'unusedFunction' is imported but not called or referenced

Code Quality & Potential Hazards

  1. eval-usage

    • Description: Use of the eval() function, which can be a security risk and hinder performance.
    • Example:
      const result = eval('1 + 1');
  2. console-usage

    • Description: Presence of console.log(), console.warn(), etc., which are often left over from debugging.
    • Example:
      function myFunc(data) {
        console.log('Debugging data:', data);
        return data;
      }
  3. debugger-statement

    • Description: A debugger; statement found, which can halt execution if developer tools are open.
    • Example:
      if (criticalCondition) {
        debugger; // Pauses execution here
      }
  4. duplicate-object-key

    • Description: An object literal contains duplicate keys, where later keys will overwrite earlier ones.
    • Example:
      const config = {
        url: 'http://example.com',
        timeout: 5000,
        url: 'http://test.com' // 'url' key is duplicated
      };

Variable & Identifier Issues

  1. undeclared-identifier

    • Description: A variable or function is used without being declared in the current scope or imported.
    • Example:
      function process() {
        const result = myUndeclaredVariable * 10; // 'myUndeclaredVariable' is not defined
        return result;
      }
  2. undeclared-jsx-component

    • Description: A JSX component (typically starting with an uppercase letter) is used without being declared or imported.
    • Example:
      // MyComponent.jsx (assuming MyButton is not imported or defined)
      function MyComponent() {
        return <MyButton label="Click Me" />;
      }

File System Issues

  1. file-not-found (when analyzing a single file directly or an import resolves to a non-existent file)
    • Description: The target file specified for analysis or an imported file path does not exist.
    • Example (CLI): ai-linter ./path/to/non-existent-file.js
    • Example (Import):
      import settings from './missing-settings'; // if './missing-settings.js' doesn't exist

Comment-Based Issues

  1. todo-comment

    • Description: A // TODO: or /* TODO: */ comment is found, indicating pending work.
    • Example:
      // TODO: Refactor this function for better performance
      function oldFunction() { /* ... */ }
  2. fixme-comment

    • Description: A // FIXME: or /* FIXME: */ comment is found, indicating a known bug or issue that needs fixing.
    • Example:
      // FIXME: This calculation is sometimes incorrect under X condition
      const value = complexCalculation();

Contributing

Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.

License

This project is open-source and available under the MIT License.