package-health-score
v1.0.2
Published
Analyze npm packages and produce a 0-100 Health Score based on maintenance, security, reliability, and activity metrics
Maintainers
Readme
📦 package-health-score
A comprehensive npm package analyzer that produces a 0-100 Health Score based on maintenance, security, reliability, and activity metrics.
🎯 Features
- NPM Registry Analysis: Last published date, publish frequency, version count, maintainer count
- GitHub Repository Metrics: Last commit, open issues/PRs, contributors, stars, watchers, forks
- Security Assessment: Vulnerability scanning via npm advisory API
- Package Structure Evaluation: Dependencies, tests, CI config, documentation, TypeScript support
- Comprehensive Scoring: Normalized 0-100 health score with detailed breakdown
- CLI Tool: Easy-to-use command-line interface
- Programmatic API: Use as a library in your own projects
📥 Installation
npm install -g package-health-scoreOr use with npx:
npx package-health-score <package-name>🚀 Quick Start
CLI Usage
Analyze a single package:
package-health-score expressAnalyze all dependencies in a package.json:
package-health-score --file ./package.jsonOutput as JSON:
package-health-score express --jsonFilter packages below a threshold:
package-health-score --file ./package.json --min 60Save results to file:
package-health-score express --save results.jsonTip: For better GitHub metrics (especially when analyzing multiple packages), set a GITHUB_TOKEN environment variable. See the Configuration section for details.
Programmatic API
import { getHealthScore, getMultipleScores } from 'package-health-score';
// Single package
const result = await getHealthScore('express');
console.log(result.score); // 85.5
console.log(result.details);
// Multiple packages
const results = await getMultipleScores(['express', 'lodash', 'axios']);
results.forEach(r => {
console.log(`${r.packageName}: ${r.score}`);
});📊 Sample Output
================================================================================
Package Score Last Update Issues Vulnerabilities
================================================================================
express 85.50 2mo ago 12 0
lodash 92.30 1mo ago 5 0
axios 88.10 3w ago 8 1
================================================================================
📊 Detailed Breakdown:
NPM Score: 22.50/25
GitHub Score: 26.80/30
Security Score: 25.00/25
Structure Score: 11.20/20
─────────────────────────────────────
Total Score: 85.50/100🔢 Score Calculation
The health score is calculated from four categories with the following weights:
1. NPM Metrics (25 points)
Last Published Date (10 points): Recency of last publish
- Published within last month: 10 points
- Published within last 6 months: 7 points
- Published within last year: 4 points
- Older than 1 year: 0-2 points
Publish Frequency (8 points): Number of publishes in last 12 months
- 12+ publishes: 8 points
- 6-11 publishes: 5-7 points
- 1-5 publishes: 2-4 points
- 0 publishes: 0 points
Version Count (4 points): Total number of versions
- 50+ versions: 4 points
- 20-49 versions: 2-3 points
- 1-19 versions: 0-1 points
Maintainer Count (3 points): Number of maintainers
- 5+ maintainers: 3 points
- 2-4 maintainers: 1-2 points
- 1 maintainer: 0.5 points
2. GitHub Metrics (30 points)
Last Commit (10 points): Recency of last commit
- Within last week: 10 points
- Within last month: 8 points
- Within last 3 months: 5 points
- Within last 6 months: 2 points
- Older: 0 points
Stars (5 points): Repository popularity
- 1000+ stars: 5 points
- 100-999 stars: 2-4 points
- 1-99 stars: 0-1 points
Contributors (5 points): Number of contributors
- 10+ contributors: 5 points
- 5-9 contributors: 3-4 points
- 1-4 contributors: 1-2 points
Open Issues (5 points): Inverse score (fewer is better)
- 0 issues: 5 points
- 1-10 issues: 4 points
- 11-25 issues: 2-3 points
- 26-50 issues: 1 point
- 50+ issues: 0 points
Open PRs (3 points): Inverse score (fewer is better)
- 0 PRs: 3 points
- 1-5 PRs: 2 points
- 6-10 PRs: 1 point
- 10+ PRs: 0 points
Forks (2 points): Repository forks
- 100+ forks: 2 points
- 10-99 forks: 1 point
- <10 forks: 0 points
3. Security Metrics (25 points)
Penalty-based system starting at 25 points:
- Critical Vulnerabilities: -10 points each
- High Vulnerabilities: -5 points each
- Moderate Vulnerabilities: -2 points each
- Low Vulnerabilities: -0.5 points each
Minimum score: 0 points
4. Structure Metrics (20 points)
- Has Tests (5 points): Presence of test directory/files
- Has CI (5 points): CI configuration (GitHub Actions, CircleCI, Travis, etc.)
- Has README (3 points): README file present
- Has License (2 points): LICENSE file present
- TypeScript Support (2 points): TypeScript in dependencies
- Dependency Count (3 points): Inverse score (fewer dependencies = better)
- 0-10 dependencies: 3 points
- 11-25 dependencies: 2 points
- 26-50 dependencies: 1 point
- 50+ dependencies: 0 points
📖 API Reference
getHealthScore(packageName: string): Promise<HealthScoreResult>
Analyzes a single package and returns its health score.
Parameters:
packageName(string): The npm package name to analyze
Returns:
Promise<HealthScoreResult>: Health score result object
Example:
const result = await getHealthScore('express');
console.log(result.score); // 85.5
console.log(result.details.npm.score); // 22.5getMultipleScores(packages: string[]): Promise<HealthScoreResult[]>
Analyzes multiple packages in parallel.
Parameters:
packages(string[]): Array of package names to analyze
Returns:
Promise<HealthScoreResult[]>: Array of health score results
Example:
const results = await getMultipleScores(['express', 'lodash']);
results.forEach(r => console.log(`${r.packageName}: ${r.score}`));HealthScoreResult
interface HealthScoreResult {
packageName: string;
score: number; // 0-100
details: {
npm: {
metrics: NpmMetrics;
score: number; // 0-25
};
github: {
metrics: GitHubMetrics;
score: number; // 0-30
};
security: {
metrics: SecurityMetrics;
score: number; // 0-25
};
structure: {
metrics: StructureMetrics;
score: number; // 0-20
};
};
}🛠️ Development
Prerequisites
- Node.js >= 18.0.0
- npm or yarn
Setup
# Clone the repository
git clone https://github.com/zohaibzebi66-dot/package-health-score.git
cd package-health-score
# Install dependencies
npm install
# Build the project
npm run build
# Run tests
npm test
# Run tests with coverage
npm run test:coverageProject Structure
package-health-score/
├── src/
│ ├── api/
│ │ ├── npmService.ts # NPM registry API client
│ │ ├── githubService.ts # GitHub API client
│ │ ├── securityService.ts # Security advisory API client
│ │ └── structureService.ts # Package structure analyzer
│ ├── core/
│ │ ├── scoreCalculator.ts # Score calculation logic
│ │ └── normalizer.ts # Metric normalization utilities
│ ├── bin/
│ │ └── cli.ts # CLI entry point
│ └── index.ts # Main API exports
├── tests/
│ ├── npmService.test.ts
│ ├── githubService.test.ts
│ ├── scoreCalculator.test.ts
│ └── index.test.ts
├── dist/ # Compiled output
├── package.json
├── tsconfig.json
└── README.md🧪 Testing
The project uses Jest for testing. Run tests with:
npm testTest coverage includes:
- Score calculation logic
- API error handling
- Missing GitHub repo fallback
- CLI argument parsing
- Edge cases and error scenarios
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Guidelines
- Follow TypeScript best practices
- Write tests for new features
- Update documentation as needed
- Ensure all tests pass before submitting PR
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
🗺️ Roadmap
Planned Features
- [ ] Caching mechanism for API responses
- [ ] Support for private npm registries
- [ ] Additional metrics (bundle size, download counts)
- [ ] Historical score tracking
- [ ] Web dashboard
- [ ] GitHub Action integration
- [ ] Support for other package managers (yarn, pnpm)
- [ ] Custom scoring weights configuration
- [ ] Export to various formats (CSV, Markdown)
Known Limitations
- GitHub API Rate Limiting: Without a GitHub token, you're limited to 60 requests/hour. This may cause GitHub metrics to show as 0 when analyzing multiple packages. Use a
GITHUB_TOKENenvironment variable to increase this to 5,000 requests/hour (see Configuration section). - Caching: Responses are cached in-memory to reduce API calls. Cache durations: NPM (10 min), GitHub (5 min), Security (30 min).
- Security advisories may not cover all vulnerability sources
- Non-GitHub repositories have limited metrics
- Some metrics require repository access (may fail for private repos)
⚙️ Configuration
GitHub API Rate Limiting
The package uses the GitHub API to fetch repository metrics. GitHub has rate limits for API requests:
- Without authentication: 60 requests per hour per IP address
- With authentication: 5,000 requests per hour per token
Using a GitHub Token (Recommended)
To increase the rate limit and avoid hitting API limits, you can provide a GitHub Personal Access Token:
- Create a token at https://github.com/settings/tokens
- No special permissions are required (public repo access is sufficient)
- Set it as an environment variable:
# Option 1: GITHUB_TOKEN
export GITHUB_TOKEN=your_token_here
# Option 2: GH_TOKEN (alternative name)
export GH_TOKEN=your_token_here
# Option 3: GITHUB_PAT (alternative name)
export GITHUB_PAT=your_token_hereThe package will automatically detect and use any of these environment variables.
Windows (PowerShell):
$env:GITHUB_TOKEN="your_token_here"Windows (CMD):
set GITHUB_TOKEN=your_token_hereCaching
The package includes built-in caching to reduce API calls and improve performance:
- NPM data: Cached for 10 minutes
- GitHub data: Cached for 5 minutes
- Security advisories: Cached for 30 minutes
- 404 responses: Cached for 1 minute (to avoid repeated failed requests)
Cache is stored in-memory and is cleared when the process exits. This means:
- Multiple analyses of the same package within the cache TTL will use cached data
- No persistent cache files are created
- Cache is automatically cleaned up when entries expire
🐛 Troubleshooting
Common Issues
Error: Package not found
- Verify the package name is correct
- Check if the package exists on npm registry
Error: Network timeout
- Check your internet connection
- GitHub API may be rate-limited (wait and retry, or use a GitHub token)
GitHub metrics showing 0 or missing
- This usually indicates GitHub API rate limiting
- Solution: Set a
GITHUB_TOKENenvironment variable (see Configuration section above) - Without a token, you're limited to 60 requests/hour
- The package gracefully handles rate limits by returning 0 for GitHub metrics
Low scores for valid packages
- Some packages may not have GitHub repositories
- Older packages may have lower scores due to recency metrics
- Check the detailed breakdown to understand score components
- If GitHub metrics are 0, consider using a GitHub token
📞 Support
If you encounter any issues or have questions:
- Check the Issues page
- Create a new issue with detailed information
- Include package name, error messages, and steps to reproduce
🙏 Acknowledgments
- npm registry API
- GitHub API
- npm security advisories API
- All contributors and users of this package
Made with ❤️ for the npm ecosystem
