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

codebase-health-check

v2.3.2

Published

Analyze your codebase for unused imports, exports, orphan files, dead code, and unused i18n keys.

Readme

Codebase Health Check

A static analysis CLI tool for Next.js, React, and TypeScript projects. Detects unused code, performance bottlenecks, and code quality issues. Provides interactive fixing with review-before-apply workflow.

Quick Start (No Installation Required)

You can run the tool directly using npx. npx will temporarily download and execute the tool on-the-fly without saving it permanently to your computer. Just navigate to your project directory and run:

# Code Cleanup (Unused imports, exports, files, i18n keys)
npx codebase-health-check analyze -d . --fix

# Performance (Unused packages, circular deps, console.logs, assets)
npx codebase-health-check analyze performance -d . --fix

# Code Quality (Large files, duplicate code, TODOs, env vars)
npx codebase-health-check analyze quality -d . --fix

Global Installation (Optional)

If you plan to use the tool frequently across multiple projects, you can install it globally on your machine. This makes the shorter chc command available everywhere.

npm install -g codebase-health-check

# Now you can use the short command:
chc analyze -d . --fix

Analysis Modes

| Command | Purpose | | --------------------------- | ---------------------------------------------------------------------------- | | analyze or analyze code | Unused imports, exports, orphan files, commented-out refs, unused i18n keys | | analyze performance | Unused npm packages, circular deps, console statements, unused public assets | | analyze quality | Large files, duplicate code, TODO/FIXME markers, unused env variables |

Each mode generates a markdown report and supports --fix for interactive fixing.


Code Cleanup

🔴 Unused Imports

Import statements that are never referenced in the file body. The tool parses the AST (Abstract Syntax Tree) to accurately distinguish between an identifier declared in an import and the same identifier used in executable code.

Cause: Refactoring that removes usage but leaves the import. Copy-pasting code between files.

// Before
import { ArrowRight, Loader2 } from 'lucide-react';
import { useEffect, useState } from 'react';

export default function MyComponent() {
  useEffect(() => {}, []);
  return <ArrowRight />;
}

// After fix — Loader2 and useState removed
import { ArrowRight } from 'lucide-react';
import { useEffect } from 'react';

export default function MyComponent() {
  useEffect(() => {}, []);
  return <ArrowRight />;
}

Fix behavior: Removes individual specifiers from the import clause. If all specifiers are unused, removes the entire import statement.


🟠 Unused Exports

Functions, types, variables, or classes marked with export that are never imported by any other file in the project. The tool scans every source file and checks whether each exported name appears in another file's import statements.

Cause: Utility functions written for features that were later removed. Speculative exports created "just in case."

// Before — formatPriceWithTax is exported but never imported anywhere
export function formatPriceWithTax(price: number, tax: number): string {
  return `$${(price * (1 + tax)).toFixed(2)}`;
}

// After fix — export keyword removed, function preserved
function formatPriceWithTax(price: number, tax: number): string {
  return `$${(price * (1 + tax)).toFixed(2)}`;
}

Fix behavior: Strips the export keyword. The declaration itself is preserved because it may be used locally. If it isn't, subsequent runs will flag it.

Risk: Exports consumed by external projects or dynamically loaded modules won't be detected as "used." The tool prompts for confirmation and supports exclusion lists.


🟡 Orphan Files

Source files that exist in the project directory but are never referenced via import or export from in any other file. These are fully disconnected from the module graph.

Cause: Replaced components left behind after refactoring. Files copied from other projects for reference. Experimental code that was never integrated.

src/components/
  header.tsx          ← imported by layout.tsx
  search-box.tsx      ← imported by header.tsx
  search-box-old.tsx  ← not imported anywhere (orphan)

Fix behavior: Deletes the file. The tool supports exclusion lists for files you intentionally keep (e.g., work-in-progress).

Automatic exclusions: Next.js entry points (page.tsx, layout.tsx, route.ts, middleware.ts, loading.tsx, error.tsx, not-found.tsx) are never flagged as orphans because the framework consumes them implicitly.


🔵 Commented-out References

A sub-category of orphan files. The file itself is an orphan (not imported anywhere), but its component name still appears inside commented-out JSX or JavaScript in another file. This indicates a component that was intentionally disabled but never cleaned up.

Cause: Temporarily disabling a component with {/*<Component />*/} and removing its import, then forgetting about both.

// layout.tsx — before
<Header />
{/*<CookieConsent />*/}   // ← commented-out reference
<Footer />

// layout.tsx — after fix
<Header />
<Footer />

The file cookie-consent.tsx is also deleted.

Fix behavior: Two operations: (1) deletes the orphan source file, (2) removes the commented-out lines from referencing files.


🟢 Unused i18n Keys

Translation keys defined in locale JSON files (e.g., messages/fr.json) that are never referenced in any source file. The tool understands next-intl patterns including useTranslations('namespace') and getTranslations('namespace').

Cause: Removed UI sections whose translation keys remain. Keys added speculatively during development.

// Before
{
  "cart": {
    "title": "Panier",
    "empty": "Votre panier est vide",
    "summer_sale_2023": "Offre spéciale été 2023!"
  }
}

// After fix — summer_sale_2023 removed
{
  "cart": {
    "title": "Panier",
    "empty": "Votre panier est vide"
  }
}

Fix behavior: Deletes unused keys from all locale files in the messages directory (fr.json, en.json, tr.json, etc.), not just the primary one.

Dynamic key handling: If a key's parent namespace is used with a variable (e.g., t(dynamicKey)), the tool classifies those keys as "potentially dynamic" and does not auto-delete them.


Performance

🔴 Unused npm Dependencies

Packages listed in package.json (dependencies and devDependencies) that are never imported or required in any source file. These inflate node_modules size, slow down installation, and increase the attack surface.

Cause: Trying a package and deciding not to use it. Migrating from one library to another without removing the old one.

Fix behavior: Prints exact npm uninstall commands. Auto-removal is intentionally avoided because some packages are consumed implicitly (PostCSS plugins, ESLint configs, TypeScript type definitions). Common implicit packages are pre-excluded.


🟠 Circular Dependencies

Import cycles where File A imports File B, which imports File C, which imports File A. These cause unpredictable module initialization order, undefined values at runtime, and slower bundling.

Cause: Utility modules that gradually start depending on each other. Shared type files importing from files that import them back.

auth.ts → user.ts → permissions.ts → auth.ts

Fix behavior: Informational only. The report shows exact cycle paths. Common resolution strategies: extract shared types into a dedicated file, use dependency injection, or restructure module boundaries.


🟡 Console Statements

console.log, console.warn, console.error, console.debug, and console.info calls left in source code. These are almost always debugging leftovers that should not reach production.

Cause: Debugging during development. Copy-pasted code from documentation or Stack Overflow.

// Before
export function addToCart(item: CartItem) {
  console.log('addToCart called', item);
  return dispatch({ type: 'ADD', payload: item });
}

// After fix
export function addToCart(item: CartItem) {
  return dispatch({ type: 'ADD', payload: item });
}

Fix behavior: Removes the entire statement line, including multi-line console calls. Lines inside comments are ignored.


🔵 Unused Public Assets

Files in the public/ directory (images, fonts, PDFs, videos) that are never referenced by filename in any source file, CSS file, or configuration file. These inflate the deployment bundle.

Cause: Replacing images without deleting the old versions. Assets downloaded for designs that were never implemented.

Fix behavior: Deletes unreferenced files. favicon.ico, robots.txt, sitemap.xml, and manifest.json are automatically excluded.


Code Quality

🔴 Large Files

Source files exceeding 300 lines. Large files typically contain multiple concerns and benefit from being split into focused modules.

Fix behavior: Informational. The report lists files sorted by line count to help prioritize refactoring.


🟠 Duplicate Code Blocks

Blocks of 6+ consecutive lines that are identical across two or more files. These indicate copy-paste patterns that should be extracted into shared utilities.

Fix behavior: Informational. The report shows the duplicated code and all locations where it appears.


🟡 TODO/FIXME/HACK Comments

Comments containing TODO, FIXME, HACK, XXX, or BUG markers. These represent acknowledged technical debt.

Fix behavior: Informational. The report groups findings by marker type with file locations and content.


🟢 Unused Environment Variables

Variables defined in .env, .env.local, or .env.production that are never referenced via process.env.VARIABLE_NAME in source or config files.

Cause: Removed features whose env variables remain. Renaming variables in code without updating .env.

Fix behavior: Informational. Variables like NODE_ENV, PORT, and HOSTNAME are automatically excluded.


Interactive Fix Workflow

Adding --fix to any analysis command enters interactive mode:

npx codebase-health-check analyze -d . --fix
npx codebase-health-check analyze performance -d . --fix

Step 1 — Select issues:

  #   Issue                        Count
  ─── ──────────────────────────── ────────────────────
  1   🔴 Unused Imports              8 in 4 files
  2   🟠 Unused Exports              192 in 92 files
  3   🟡 Orphan Files                74 files
  4   🔵 Commented-out Refs          16 files
  5   🟢 Unused i18n Keys            3 keys

  Select issues to fix (numbers or "all"): 1,3,4

Step 2 — Review destructive operations:

  Orphan Files — this is a destructive operation.
  review and exclude some? (y/n): y

  fix plan saved: /project/chc-fix-plan.json
  edit the "exclude" arrays, then run:
  npx codebase-health-check fix

Step 3 — Edit and apply:

Add paths to the "exclude" array in the generated JSON file, then:

npx codebase-health-check fix -d .

If no exclusions are needed, answer n to the review prompt and fixes are applied immediately.


Options

| Option | Default | Description | | -------------------------- | ---------- | -------------------------------- | | -d, --dir <path> | . | Root directory to analyze | | -l, --locales-dir <path> | messages | Locale JSON directory | | --default-locale <file> | fr.json | Primary locale file for analysis | | --fix | false | Enable interactive fix mode |

Generated Reports

| Command | Output file | | -------------------------- | ----------------------------- | | analyze / analyze code | health-check-report.md | | analyze performance | health-check-performance.md | | analyze quality | health-check-quality.md |

Framework Support

  • Next.js (App Router and Pages Router)
  • React (TypeScript and JavaScript)
  • next-intl (namespace-aware i18n analysis)
  • Path aliases (@/ resolves to src/)

Ignoring Files

Create .chcignore in the project root (.gitignore syntax):

**/*.test.ts
**/*.spec.ts
src/legacy/**

Existing .gitignore rules are also respected.

License

MIT