rasul-nodemodules-cleaner
v1.2.0
Published
Production-grade dependency hygiene tool for Node.js — detect unused, missing, duplicated, and bloated dependencies with low false positives and CI-ready output
Maintainers
Readme
🛡️ dep-guardian
Production-Grade Dependency Hygiene for Node.js
Detect unused, missing, and duplicate dependencies with low false positives and CI-ready output.
📦 Install
npm install -g rasul-nodemodules-cleaner🚀 Quick Start
dep-guardianThat's it. Your project is scanned and a full report is generated.
📊 Example Output
🛡️ dep-guardian — Dependency Hygiene Report
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📂 Path: /my-project
📄 Scanned: 42 files
📦 Dependencies: 18
⚠️ Unused Dependencies (3)
🔴 lodash (95%) — Safe to remove
🟡 moment (72%) — Review before removing
⚪ uuid (55%) — Possibly unused
❌ Missing Dependencies (1)
zod — used in src/utils.ts
✅ No duplicate dependencies found.
📊 Confidence: 1 high · 1 medium · 1 low🎯 Commands
| Command | Description |
|:--------|:------------|
| dep-guardian | 🔍 Run full analysis (default) |
| dep-guardian unused | 📋 Show only unused dependencies |
| dep-guardian remove | 🗑️ Safely remove unused dependencies |
| dep-guardian ci | 🤖 CI mode with configurable exit codes |
| dep-guardian baseline-save | 💾 Save current state for trend tracking |
| dep-guardian baseline-compare | 📈 Compare against saved baseline |
| dep-guardian workspace | 🏢 Analyze monorepo workspaces |
⚙️ Options
| Flag | Description | Default |
|:-----|:------------|:--------|
| --path <dir> | 📂 Project path to analyze | . |
| --format <fmt> | 🖥️ Output format: console, json | console |
| --confidence <n> | 🎯 Minimum confidence threshold (0-100) | 50 |
| --dryRun | 👁️ Preview removal without changes | false |
| --cleanImports | 🧹 Remove dead imports after uninstall | false |
| --yes | ✅ Skip confirmation prompts | false |
| --failOnUnused <n> | 🚫 CI: fail if more than N unused deps | 0 |
| --failOnConfidence <n> | 🎚️ CI: only count deps above this confidence | 90 |
🔬 How It Works
dep-guardian scans your project from 4 layers to maximize accuracy:
┌─────────────────────────────────────────────────────┐
│ 🔍 SCANNING │
├─────────────────────────────────────────────────────┤
│ │
│ 📄 Source Files → imports, requires, dynamic │
│ ⚙️ Config Files → ESLint, Babel, Jest, etc. │
│ 📜 Package Scripts → CLI binary references │
│ 🤖 CI Workflows → GitHub Actions, GitLab CI │
│ │
├─────────────────────────────────────────────────────┤
│ 🧮 SCORING │
├─────────────────────────────────────────────────────┤
│ │
│ Evidence from all 4 sources is combined into │
│ a confidence score (0-100) for each dependency. │
│ │
└─────────────────────────────────────────────────────┘📄 Source File Scanning
Extracts dependency references from:
- ✅ ESM imports (
import X from 'pkg') - ✅ CommonJS requires (
require('pkg')) - ✅ Dynamic imports (
import('pkg')) - ✅ Re-exports (
export ... from 'pkg') - ✅ require.resolve (
require.resolve('pkg'))
Supported extensions: .js, .jsx, .ts, .tsx, .mjs, .cjs, .mts, .cts
⚙️ Config File Detection
Automatically detects references in:
| Category | Config Files |
|:---------|:-------------|
| 🔧 ESLint | .eslintrc.*, eslint.config.* |
| 🎨 Babel | babel.config.*, .babelrc* |
| 🎨 PostCSS | postcss.config.*, .postcssrc* |
| 💅 Prettier | .prettierrc*, prettier.config.* |
| 🌊 Tailwind | tailwind.config.* |
| ⚡ Vite | vite.config.* |
| 🃏 Jest | jest.config.* |
| 🧪 Vitest | vitest.config.* |
| 📝 TypeScript | tsconfig.json, tsconfig.*.json |
| 📋 Commitlint | commitlint.config.* |
| 📌 lint-staged | .lintstagedrc* |
🤖 CI Workflow Scanning
Supports 7 CI platforms:
- 🐙 GitHub Actions
- 🦊 GitLab CI
- 🔵 CircleCI
- 🔵 Azure Pipelines
- 🟦 Bitbucket Pipelines
- 🤖 Dependabot
- 🔄 Renovate
🎚️ Confidence Scores
Each unused dependency receives a confidence score indicating how likely it is truly unused:
| Score | Label | Emoji | Action | |:------|:------|:------|:-------| | 90-100 | High | 🔴 | Safe to remove | | 70-89 | Medium | 🟡 | Review before removing | | 50-69 | Low | ⚪ | Manual verification needed | | <50 | Ambiguous | ⚪ | Not enough evidence — keep |
🧮 Scoring Algorithm
Base Score: 50
Adjustments:
📁 < 5 files scanned → -20
📦 Peer dependency → -30
📦 Optional dependency → -15
⚙️ Has config references → +25
📜 Has script references → +20
🤖 Has CI references → +15
🚫 Zero evidence (all 4) → +20
📁 > 20 files scanned → +5
📁 > 50 files scanned → +5
📁 > 100 files scanned → +5🗑️ Safe Removal
The remove command provides a safe, multi-step removal workflow:
# 👁️ Preview what would be removed
dep-guardian remove --dryRun
# 🗑️ Remove with confirmation prompts
dep-guardian remove
# ✅ Auto-confirm and clean dead imports
dep-guardian remove --yes --cleanImports🔄 Removal Flow
┌──────────────────────────────────────┐
│ 1️⃣ Run Analysis │
├──────────────────────────────────────┤
│ 2️⃣ Filter by Confidence Threshold │
├──────────────────────────────────────┤
│ 3️⃣ Display Candidates │
├──────────────────────────────────────┤
│ 4️⃣ Confirm with User │
├──────────────────────────────────────┤
│ 5️⃣ Backup package.json │
├──────────────────────────────────────┤
│ 6️⃣ Auto-detect Package Manager │
├──────────────────────────────────────┤
│ 7️⃣ Uninstall Dependencies │
├──────────────────────────────────────┤
│ 8️⃣ Clean Dead Imports (optional) │
├──────────────────────────────────────┤
│ 9️⃣ Run Tests to Verify │
├──────────────────────────────────────┤
│ 🔟 Rollback if Tests Fail │
└──────────────────────────────────────┘📦 Package Manager Support
dep-guardian auto-detects your package manager:
| Manager | Detection Method |
|:--------|:-----------------|
| 🟩 pnpm | pnpm-lock.yaml |
| 🟨 yarn | yarn.lock |
| 🟫 bun | bun.lockb |
| 🟦 npm | Default fallback |
🤖 CI Integration
GitHub Actions Example
- name: Check Dependencies
run: npx rasul-nodemodules-cleaner ci --failOnUnused 3 --failOnConfidence 90Exit Codes
| Code | Meaning |
|:-----|:--------|
| 0 | ✅ All checks passed |
| 1 | 🚫 Unused dependencies found or threshold exceeded |
📊 JSON Output
dep-guardian ci --format json{
"totalDependencies": 18,
"scannedFiles": 42,
"summary": {
"unused": 3,
"missing": 1,
"duplicates": 0
},
"unused": [
{
"name": "lodash",
"confidence": 95,
"reason": "No references found in source files, configs, scripts, or CI",
"risk": "low"
}
]
}📈 Baseline Tracking
Track dependency changes over time:
# 💾 Save current state
dep-guardian baseline-save
# 📈 Later, compare for regressions
dep-guardian baseline-compare📊 Diff Output
{
"newUnused": ["moment"],
"resolvedUnused": ["lodash"],
"newMissing": ["zod"],
"resolvedMissing": ["axios"]
}🏢 Workspace / Monorepo Support
# 🏢 Analyze all workspaces
dep-guardian workspace
# 🎯 Analyze a specific workspace
dep-guardian workspace --name my-packageSupports both workspace formats:
// Array format
{ "workspaces": ["packages/*", "apps/*"] }
// Object format
{ "workspaces": { "packages": ["packages/*"] } }🔧 Programmatic API
Use dep-guardian as a library in your own tools:
import {
analyze,
printReport,
jsonReport,
removeDependencies,
detectWorkspaces,
analyzeWorkspaces
} from 'rasul-nodemodules-cleaner';
// Run analysis
const result = await analyze({
path: '.',
minConfidence: 70,
onlyUnused: true
});
// Print colored report
printReport(result);
// Get JSON output
const json = jsonReport(result);
// Detect monorepo workspaces
const workspaces = await detectWorkspaces('.');
// Analyze all workspaces
const results = await analyzeWorkspaces('.');📋 Supported File Extensions
| Type | Extensions |
|:-----|:-----------|
| 📄 JavaScript | .js, .mjs, .cjs |
| 📄 TypeScript | .ts, .mts, .cts |
| 📄 React | .jsx, .tsx |
🛡️ Excluded Directories
These directories are automatically excluded from scanning:
node_modules/dist/build/.next/coverage/__tests__/__mocks__/
⚠️ Known Limitations
| Limitation | Description |
|:-----------|:------------|
| 📦 @types/* | Always appear unused (type-only, no runtime imports) |
| 🔄 Dynamic imports | Non-literal arguments cannot be statically analyzed |
| 🔌 Framework plugins | Some auto-load by naming convention (e.g., gatsby-*) |
| 📎 Peer dependencies | Get low confidence but may be required |
📄 License
Made with ❤️ for the Node.js community
