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 🙏

© 2025 – Pkg Stats / Ryan Hefner

tscanner

v0.0.33

Published

Code quality scanner for the AI-generated code era

Readme

🎺 Overview

Scan your codebase from the terminal. Run before commits, in CI pipelines, or as part of your build. Get JSON output for tooling or pretty output for humans. Same rules as the VS Code extension.

⭐ Features

  • Your Rules, Enforced - 38 built-in checks + define your own with regex, scripts, or AI
  • Sub-second Scans - Rust engine processes hundreds of files in <1s, with smart caching
  • Focus on What Matters - Scan your branch changes only, or audit the full codebase
  • CI-Ready - JSON output for automation, exit codes for pipelines

❓ Motivation

AI generates code fast, but it doesn't know your project's conventions, preferred patterns, or forbidden shortcuts. You end up reviewing the same issues over and over.

TScanner lets you define those rules once. Every AI-generated file, every PR, every save: automatically checked against your standards. Stop repeating yourself in code reviews.

  • Project Consistency - Enforce import styles, naming conventions, and code organization rules
  • PR Quality Gates - Auto-comment violations before merge so reviewers focus on logic
  • AI Code Validation - Real-time feedback on AI-generated code before accepting
  • Flexible Customization - Built-in rules + custom scripts and AI rules for complex logic

🚀 Quick Start

  1. Install locally
npm install -D tscanner
  1. Initialize configuration
tscanner init

Tip: Use tscanner init --full for a complete config with example regex, script, and AI rules.

After that you can already use the CLI:

  1. Check via terminal
# Scan workspace
tscanner check

# Scan only changed files vs branch
tscanner check --branch origin/main
  1. Integrate with lint-staged (optional)
// .lintstagedrc.json
{
  "*": ["npx tscanner check --staged"]
}

📖 Usage

⚙️ Configuration

To scan your code, you need to set up the rules in the TScanner config folder. Here's how to get started:

  1. CLI: Run tscanner init in your project root (Recommended)
  2. Manual: Copy the default config below to .tscanner/config.jsonc
{
  "$schema": "https://unpkg.com/[email protected]/schema.json",
  "files": {
    "include": [
      "**/*.ts",
      "**/*.tsx",
      "**/*.js",
      "**/*.jsx",
      "**/*.mjs",
      "**/*.cjs",
      "**/*mts",
      "**/*cts"
    ],
    "exclude": [
      "**/node_modules/**",
      "**/dist/**",
      "**/build/**",
      "**/.git/**",
      "**/.next/**"
    ]
  },
  "codeEditor": {
    "highlightErrors": true,
    "highlightWarnings": true,
    "highlightInfos": true,
    "highlightHints": true,
    "scanInterval": 0,
    "aiScanInterval": 0
  }
}

All configuration fields are optional with sensible defaults. The minimum required config is just enabling the rules you want:

{
  "rules": {
    "builtin": {
      "no-explicit-any": {}
    }
  }
}

With this minimal config, TScanner will scan all .ts/.tsx/.js/.jsx/.mjs/.cjs files, excluding node_modules/, dist/, build/, and .git/ directories.

Understanding files.include and files.exclude:

  • files.include: Glob patterns for files to scan (default: ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.mjs", "**/*.cjs"])
  • files.exclude: Glob patterns for files/folders to ignore (default: ["**/node_modules/**", "**/dist/**", "**/build/**", "**/.git/**"])

Example with per-rule file patterns:

{
  "rules": {
    "builtin": {
      "no-explicit-any": {},
      "no-console": {
        "exclude": ["src/utils/logger.ts"]
      },
      "max-function-length": {
        "include": ["src/core/**/*.ts"]
      }
    }
  }
}

This config:

  • Runs no-explicit-any on all files (uses global files patterns)
  • Runs no-console on all files except src/utils/logger.ts
  • Runs max-function-length only on files inside src/core/

Inline Disables:

// tscanner-ignore-next-line no-explicit-any
const data: any = fetchData();

// tscanner-ignore
// Entire file is skipped

📋 Rules

Customize TScanner to validate what matters to your project while maintaining consistency.

Type Safety (6)

Code Quality (13)

Bug Prevention (4)

Variables (3)

Imports (8)

Style (4)

Define patterns to match in your code using regular expressions:

Config (.tscanner/config.jsonc):

{
  "rules": {
    "regex": {
      "no-todos": {
        "pattern": "TODO:|FIXME:",
        "message": "Remove TODO comments before merging",
        "severity": "warning"
      },
      "no-debug-logs": {
        "pattern": "console\\.(log|debug|info)",
        "message": "Remove debug statements",
        "severity": "warning",
        "exclude": ["**/*.test.ts"]
      }
    }
  }
}

💡 See a real example in the .tscanner/ folder of this project.

Run custom scripts that receive file data via stdin and output issues as JSON:

Config (.tscanner/config.jsonc):

{
  "rules": {
    "script": {
      "no-debug-comments": {
        "command": "npx tsx .tscanner/script-rules/no-debug-comments.ts",
        "message": "Debug comments should be removed",
        "severity": "warning"
      }
    }
  }
}

Script (.tscanner/script-rules/no-debug-comments.ts):

#!/usr/bin/env npx tsx

import { stdin } from 'node:process';

type ScriptFile = {
  path: string;
  content: string;
  lines: string[];
};

type ScriptInput = {
  files: ScriptFile[];
  options?: Record<string, unknown>;
  workspaceRoot: string;
};

type ScriptIssue = {
  file: string;
  line: number;
  column?: number;
  message: string;
};

async function main() {
  let data = '';
  for await (const chunk of stdin) {
    data += chunk;
  }

  const input: ScriptInput = JSON.parse(data);
  const issues: ScriptIssue[] = [];

  for (const file of input.files) {
    for (let i = 0; i < file.lines.length; i++) {
      const line = file.lines[i];
      if (/\/\/\s*(DEBUG|HACK|XXX|TEMP)\b/i.test(line)) {
        issues.push({
          file: file.path,
          line: i + 1,
          message: `Debug comment found: "${line.trim().substring(0, 50)}"`,
        });
      }
    }
  }

  console.log(JSON.stringify({ issues }));
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});

💡 See a real example in the .tscanner/ folder of this project.

Use AI prompts to perform semantic code analysis:

Config (.tscanner/config.jsonc):

{
  "aiRules": {
    "find-complexity": {
      "prompt": "find-complexity.md",
      "mode": "content",
      "message": "Function is too complex, consider refactoring",
      "severity": "warning",
      "enabled": true
    }
  },
  "ai": {
    "provider": "claude",
    "timeout": 120
  }
}

Prompt (.tscanner/ai-rules/find-complexity.md):

# Find Complex Functions

Analyze the provided code and identify functions that are overly complex.

## What to look for

1. Functions with high cyclomatic complexity (many branches/loops)
2. Deeply nested code blocks (3+ levels)
3. Functions doing too many things (violating single responsibility)
4. Long parameter lists that should be objects

## Output format

Report each complex function with:
- The function name
- Why it's complex
- A brief suggestion for improvement

{{FILES}}

💡 See a real example in the .tscanner/ folder of this project.

💡 Inspirations

  • Biome - High-performance Rust-based linter and formatter for web projects
  • ESLint - Find and fix problems in your JavaScript code
  • Vitest - Next generation testing framework powered by Vite
  • VSCode Bookmarks - Bookmarks Extension for Visual Studio Code

🤝 Contributing

Contributions are welcome! See CONTRIBUTING.md for setup instructions and development workflow.

📜 License

MIT License - see LICENSE file for details.