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

@thestacklabs/depguard

v1.0.1

Published

Audit npm dependencies for health issues: maintenance, licenses, size, deprecation, and unused packages

Readme

@thestacklabs/depguard

Guard your npm dependencies. Audit maintenance status, license compatibility, bundle size, deprecation, and unused packages — all in a single command.

npx @thestacklabs/depguard
  depguard — [email protected]

  Overall Health Score: 74/100
  Healthy: 38  |  Warning: 7  |  Critical: 2  |  Unused: 1

  CRITICAL (2)
  ────────────────────────────────────────────────────────────
  F [email protected] [dev]  score: 5
    ! DEPRECATED: Use node-fetch or undici instead
    ! Last published 4.2 years ago

  F [email protected]  score: 0
    ! Package "left-pad" is installed but never imported

  WARNINGS (7)
  ────────────────────────────────────────────────────────────
  D [email protected]  score: 42
    ~ Last published 2.8 years ago
    ~ Unpacked size: 4.2 MB
    ~ 37 direct dependencies

Features

  • Maintenance — Flags stale/abandoned packages based on last publish date and maintainer count
  • License — Detects incompatible licenses (GPL in MIT projects, missing licenses, SPDX expressions)
  • Size — Flags bloated packages by unpacked size and dependency count
  • Deprecation — Catches deprecated packages with their replacement messages
  • Unused — Scans your source code to find installed packages that are never imported
  • Health Score — Per-dependency score (0–100) with letter grades (A–F) and an overall project score
  • Zero Dependencies — Uses only Node.js built-ins, nothing else

Install

# Run directly
npx @thestacklabs/depguard

# Or install globally
npm install -g @thestacklabs/depguard

# Or as a dev dependency
npm install --save-dev @thestacklabs/depguard

Requires Node.js 18 or later.

CLI Usage

# Basic audit
npx @thestacklabs/depguard

# JSON output for CI/CD pipelines
npx @thestacklabs/depguard --json

# Fail CI if health score drops below threshold
npx @thestacklabs/depguard --threshold 60

# Show detailed per-analyzer breakdown
npx @thestacklabs/depguard --verbose

# Exclude devDependencies
npx @thestacklabs/depguard --no-dev

# Skip unused dependency scanning
npx @thestacklabs/depguard --no-unused

# Custom source directories for unused scan
npx @thestacklabs/depguard --src src,lib,app

# Sort by name or size instead of score
npx @thestacklabs/depguard --sort name

# Show only critical issues
npx @thestacklabs/depguard --filter critical

# Generate a config file
npx @thestacklabs/depguard init

Tip: Install globally with npm i -g @thestacklabs/depguard to use depguard directly without npx.

All Options

| Flag | Description | Default | |------|-------------|---------| | --path, -p <path> | Path to package.json | ./package.json | | --json | Output as JSON | false | | --no-dev | Exclude devDependencies | includes dev | | --include-peer | Include peerDependencies | false | | --include-optional | Include optionalDependencies | false | | --concurrency, -c | Max parallel registry requests | 8 | | --threshold <n> | Min score; exit code 1 if below | none | | --sort <field> | Sort by: score, name, size | score | | --filter <level> | Show: critical, warning, all | all | | --no-unused | Skip unused dependency scanning | scans | | --src <paths> | Source dirs to scan (comma-separated) | src,lib,app,pages,components,. | | --verbose, -v | Show per-analyzer score breakdown | false | | --no-color | Disable colored output | colors on | | --help, -h | Show help | | | --version | Show version | |

Exit Codes

| Code | Meaning | |------|---------| | 0 | All dependencies above threshold (or no threshold set) | | 1 | One or more dependencies below threshold | | 2 | Execution error (e.g., package.json not found) |

Programmatic API

import { audit } from '@thestacklabs/depguard';

const report = await audit({
  packageJsonPath: './package.json',
  includeDev: false,
  concurrency: 10,
  config: {
    thresholds: {
      maintenance: { staleDays: 730 },
      size: { maxUnpackedSize: 1_000_000 },
    },
    unused: {
      srcPaths: ['src', 'lib'],
      ignore: ['my-cli-tool'],
    },
  },
});

console.log(`Overall score: ${report.summary.overallScore}/100`);

for (const dep of report.dependencies) {
  if (dep.score < 40) {
    console.log(`${dep.name}@${dep.version}: ${dep.grade} (${dep.score})`);
    for (const issue of dep.issues) {
      console.log(`  [${issue.severity}] ${issue.message}`);
    }
  }
}

API Reference

audit(options?): Promise<AuditReport>

Main entry point. Analyzes all dependencies and returns a full report.

Options:

| Property | Type | Default | Description | |----------|------|---------|-------------| | packageJsonPath | string | ./package.json | Path to package.json | | includeDev | boolean | true | Include devDependencies | | includePeer | boolean | false | Include peerDependencies | | includeOptional | boolean | false | Include optionalDependencies | | concurrency | number | 8 | Max parallel registry requests | | skipUnused | boolean | false | Skip unused dependency scanning | | srcPaths | string[] | ['src','lib',...] | Directories to scan for imports | | config | PkgHealthConfig | {} | Override config (see below) | | onProgress | function | — | Progress callback |

Returns: AuditReport

interface AuditReport {
  projectName: string;
  projectVersion: string;
  projectLicense: string | null;
  generatedAt: string;
  summary: {
    totalDependencies: number;
    healthyCount: number;      // score >= 70
    warningCount: number;      // score 40-69
    criticalCount: number;     // score < 40
    unusedCount: number;
    overallScore: number;      // 0-100
  };
  dependencies: DependencyReport[];
}

interface DependencyReport {
  name: string;
  version: string;
  dependencyType: 'production' | 'dev' | 'peer' | 'optional';
  score: number;               // 0-100
  grade: 'A' | 'B' | 'C' | 'D' | 'F';
  issues: Issue[];
  details: {
    maintenance: { lastPublished, daysSincePublish, maintainerCount, score };
    license: { license, compatibility, score };
    size: { unpackedSizeBytes, fileCount, directDependencies, score };
    deprecation: { isDeprecated, message, score };
    unused: { isUsed, score };
  };
}

Individual Analyzers

You can also use analyzers individually:

import {
  analyzeDeprecation,
  analyzeMaintenance,
  analyzeLicense,
  analyzeSize,
  analyzeUnused,
  scanUsedPackages,
  RegistryClient,
} from '@thestacklabs/depguard';

// Fetch metadata for a single package
const client = new RegistryClient();
const metadata = await client.fetchPackage('express');

// Run individual analyzers
const deprecation = analyzeDeprecation(metadata);
const maintenance = analyzeMaintenance(metadata, {});
const license = analyzeLicense(metadata, { license: { projectLicense: 'MIT' } });
const size = analyzeSize(metadata, {});

Configuration

Create a .depguardrc.json in your project root, or add a "depguard" key to your package.json.

Generate a default config:

depguard init

Config File

{
  "include": {
    "dev": true,
    "peer": false,
    "optional": false
  },
  "weights": {
    "maintenance": 0.30,
    "license": 0.20,
    "size": 0.10,
    "deprecation": 0.20,
    "unused": 0.20
  },
  "thresholds": {
    "maintenance": {
      "staleDays": 730,
      "criticalStaleDays": 1460
    },
    "size": {
      "maxUnpackedSize": 2000000,
      "maxDependencies": 30
    },
    "license": {
      "allowed": [],
      "blocked": ["GPL-3.0"]
    }
  },
  "unused": {
    "srcPaths": ["src", "lib", "app"],
    "ignore": ["my-cli-tool"]
  },
  "ignore": ["internal-pkg"]
}

Scoring

Each dependency gets a weighted score from 5 analyzers:

| Analyzer | Weight | What it checks | |----------|--------|----------------| | Maintenance | 30% | Days since last publish, maintainer count | | License | 20% | Compatibility with your project license | | Deprecation | 20% | Whether the package is deprecated | | Unused | 20% | Whether the package is actually imported in your code | | Size | 10% | Unpacked size and number of direct dependencies |

Grades: A (90+), B (75-89), C (60-74), D (40-59), F (below 40)

Unused Detection

The unused analyzer scans your source files (.js, .ts, .jsx, .tsx, .mjs, .cjs) for import and require statements. Packages in your package.json that are never imported are flagged.

Smart defaults — these are never flagged as unused:

  • Type packages (@types/*)
  • Build tools (typescript, tsup, esbuild, webpack, vite, rollup)
  • Linters/formatters (eslint, prettier, stylelint and their plugins)
  • Test runners (vitest, jest, mocha)
  • Git hooks (husky, lint-staged)
  • Packages referenced in package.json scripts

Add custom exceptions with the unused.ignore config option.

CI/CD Integration

GitHub Actions

- name: Guard dependencies
  run: npx @thestacklabs/depguard --json --threshold 60

Pre-commit Hook

{
  "scripts": {
    "guard-deps": "depguard --threshold 70 --no-unused"
  }
}

Contributing

See CONTRIBUTING.md for guidelines on how to contribute to this project.

Author

Developed by Nachat Ra Sharma at thestacklabs.

License

MIT