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

treeshake-check

v1.2.0

Published

Analyze JavaScript/TypeScript React applications for tree-shaking issues

Downloads

62

Readme

treeshake-check

A production-grade CLI tool to analyze JavaScript/TypeScript React applications for tree-shaking issues.

Features

  • 🔍 Auto-detect bundlers - Vite, Webpack, Rollup, esbuild
  • 🌳 Barrel file analysis - Detect export * patterns that break tree-shaking
  • ⚠️ Side effects detection - Find top-level code that prevents dead code elimination
  • 📦 CommonJS detection - Identify modules that don't tree-shake
  • 🔗 Unused export detection - Find exports never imported anywhere in the codebase
    • Tracks import type and inline type imports (TypeScript)
    • Tracks dynamic import() and require() calls
    • Resolves tsconfig paths aliases (e.g. @/utils)
    • Smart entry point detection (Next.js pages/app router, Remix routes, config files, etc.)
  • 🔄 Circular dependency detection - Find import cycles that prevent tree-shaking
  • 📊 Bundle stats parsing - Analyze webpack stats.json, esbuild metafile, Vite/Rollup output
  • 💡 Fix suggestions - Actionable recommendations for each issue
  • 📋 Multiple output formats - Human-readable text or JSON for CI

Installation

npm install -g treeshake-check

# Or use directly with npx
npx treeshake-check analyze

Usage

Analyze a project

# Analyze current directory (auto-detect bundler)
treeshake-check analyze

# Analyze a specific directory
treeshake-check analyze ./my-react-app

# With specific bundler stats
treeshake-check analyze --stats dist/stats.json

CLI Options

treeshake-check analyze [path] [options]

Options:
  -b, --bundler <type>       Force bundler type (vite|webpack|rollup|esbuild)
  -s, --stats <file>         Path to bundle stats/metafile
  -o, --output <format>      Output format (text|json) (default: "text")
  -t, --threshold <bytes>    Minimum size to report (default: "0")
  --no-suggestions           Hide fix suggestions
  -i, --include <patterns>   Glob patterns to include
  -e, --exclude <patterns>   Glob patterns to exclude

Generate bundle stats

Webpack

webpack --json > stats.json
treeshake-check analyze --stats stats.json

Vite/Rollup

# Install rollup-plugin-visualizer
npm install -D rollup-plugin-visualizer

# Configure in vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer';

export default defineConfig({
  plugins: [
    visualizer({ filename: 'stats.json', json: true })
  ]
});

esbuild

// Enable metafile in build
await esbuild
  .build({
    entryPoints: ["src/index.ts"],
    bundle: true,
    metafile: true,
    outfile: "dist/bundle.js",
  })
  .then((result) => {
    fs.writeFileSync("meta.json", JSON.stringify(result.metafile));
  });

Example Output

🔍 Tree-Shaking Analysis Report
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Summary:
  📁 Project: /path/to/project
  🔧 Bundler: vite
  📊 Files Analyzed: 42

  ⚠️  Issues Found: 5
     ● Critical: 1
     ● High: 2
     ● Medium: 2
  📦 Potential Savings: 85.3 KB

CRITICAL ISSUES
────────────────
1. CommonJS Module: node_modules/lodash/index.js
   └─ Pattern: require('lodash')
   └─ Impact: 72 KB
   └─ lodash CommonJS bundle is included. Use lodash-es for tree-shaking.
   └─ Fix: Switch to lodash-es
      import { debounce } from 'lodash-es'

HIGH PRIORITY ISSUES
────────────────────
2. Wildcard Re-export: src/components/index.ts
   └─ Line: 5
   └─ Pattern: export * from './Button'
   └─ Impact: 8.2 KB
   └─ Wildcard re-export prevents tree-shaking.
   └─ Fix: Use explicit named exports
      export { Button } from './Button'

JSON Output

Use --output json for CI integration:

{
  "summary": {
    "projectPath": "/path/to/project",
    "bundler": "vite",
    "totalIssues": 5,
    "criticalCount": 1,
    "highCount": 2,
    "mediumCount": 2,
    "lowCount": 0,
    "estimatedSavings": 87347,
    "analyzedFiles": 42
  },
  "issues": [
    {
      "type": "commonjs-module",
      "severity": "critical",
      "file": "node_modules/lodash/index.js",
      "pattern": "require('lodash')",
      "estimatedImpact": 72000,
      "suggestion": {
        "title": "Switch to lodash-es",
        "code": "import { debounce } from 'lodash-es'"
      }
    }
  ]
}

Issue Types

| Type | Description | | ---------------------------- | --------------------------------------------------- | | barrel-file | Barrel files with many re-exports | | wildcard-reexport | export * patterns that include all exports | | side-effect | Top-level code that runs on import | | commonjs-module | CommonJS modules that don't tree-shake | | unused-export | Exports not imported anywhere in the codebase | | circular-dependency | Circular imports that prevent tree-shaking | | dynamic-import | Dynamic imports that may bypass tree-shaking | | missing-sideeffects-config | Missing sideEffects in package.json |

License

MIT