@rayburst/sharity
Version:
Analyze shared package usage across monorepos - calculate symbol sharing percentages, track exclusive imports, and identify unused exports
332 lines (246 loc) โข 11.8 kB
Markdown
# @rayburst/sharity
> Analyze shared package usage across monorepos - calculate symbol sharing percentages, track exclusive imports, and identify unused exports
## Overview
`sharity` is a CLI tool and programmatic API that helps you understand how shared packages are used across your monorepo. It answers questions like:
- **What percentage of exports are truly shared** (used by 2+ apps)?
- **Which symbols are exclusive** to single consumers?
- **How much dead code** exists (unused exports)?
- **Which apps have high coupling** to shared packages?
Perfect for:
- ๐๏ธ **Monorepo maintenance** - Identify refactoring opportunities
- ๐ **Architecture decisions** - Understand package coupling
- ๐งน **Code cleanup** - Find unused exports
- ๐ **CI/CD integration** - Enforce sharing thresholds
## Installation
### In your monorepo (recommended)
```bash
pnpm add -D @rayburst/sharity
# or
npm install --save-dev @rayburst/sharity
# or
yarn add -D @rayburst/sharity
```
### Global installation
```bash
npm install -g @rayburst/sharity
```
## Quick Start
### CLI Usage
```bash
# Analyze a package
npx sharity packages/ui --consumers "apps/*" "packages/*"
# With verbose output
npx sharity packages/ui --consumers "apps/*" -v
# JSON output
npx sharity packages/ui -f json
# With CI threshold (fails if shared % below 50%)
npx sharity packages/ui --threshold 50
```
### As npm script
Add to your `package.json`:
```json
{
"scripts": {
"analyze:ui": "sharity packages/ui --consumers 'apps/*' 'packages/*'",
"analyze:ui:ci": "sharity packages/ui --threshold 50"
}
}
```
Then run:
```bash
npm run analyze:ui
```
### Programmatic API
```typescript
import { SharedPackageAnalyzer } from '@rayburst/sharity';
const analyzer = new SharedPackageAnalyzer({
packagePath: './packages/ui',
consumerGlobs: ['apps/*', 'packages/*'],
verbose: true,
});
const result = await analyzer.analyze();
console.log(`Shared symbols: ${result.sharedSymbolsPercentage}%`);
console.log(`Exclusive symbols: ${result.exclusiveSymbolsPercentage}%`);
console.log(`Unused symbols: ${result.unusedSymbolsPercentage}%`);
```
## CLI Options
```
Usage: sharity [options] <package-path>
Analyze shared package usage across monorepos
Arguments:
package-path Path to the package to analyze
Options:
-V, --version output the version number
-c, --consumers <globs...> Glob patterns for consumer packages
(default: ["apps/*","packages/*"])
-e, --exclude <patterns...> Patterns to exclude from analysis (default: [])
-t, --threshold <number> Minimum sharing percentage threshold for CI
(exit 1 if below)
-f, --format <type> Output format: table or json (default: "table")
--include-tests Include test files in analysis (default: false)
--config <path> Load configuration from file
-v, --verbose Verbose output (default: false)
-h, --help display help for command
```
## Example Output
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Shared Package Analysis: @myorg/ui โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโค
โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโค
โ Total Symbols โ 129 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโค
โ Shared (2+ apps) โ 34 (26.4%) โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโค
โ Exclusive (1 app) โ 95 (73.6%) โ ๏ธ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโค
โ Unused (0 apps) โ 0 (0%) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโค
โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโค
โ Total Lines โ 23,114 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโค
โ Shared lines โ 17,536 (75.87%) โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโค
โ Exclusive lines โ 3,500 (15.14%) โ ๏ธ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโค
โ Unused lines โ 2,078 (8.99%) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโ
Per-Consumer Analysis
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโฌโโโโโโโโโ
โ Consumer โ Total โ Exclusive โ Exclusive % โ Est. Lines โ Risk โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโค
โ web-client โ 87 โ 63 โ 72.4% โ 2,450 โ ๐ด โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโค
โ customer-funnel โ 38 โ 17 โ 44.7% โ 550 โ ๐ก โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโค
โ microsites โ 37 โ 8 โ 21.6% โ 400 โ ๐ข โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโดโโโโโโโโโ
```
## Configuration File
Create `.sharity.json`:
```json
{
"packagePath": "./packages/ui",
"consumerGlobs": ["apps/*", "packages/*"],
"excludePatterns": ["**/*.test.ts", "**/__mocks__/**"],
"includeTests": false,
"sharingThreshold": 50,
"outputFormat": "table",
"verbose": false
}
```
Then use it:
```bash
npx sharity --config .sharity.json
```
## CI/CD Integration
### GitHub Actions
```yaml
name: Shared Package Analysis
on: [pull_request]
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm install
- name: Analyze shared package
run: npx sharity packages/ui --threshold 50
```
### GitLab CI
```yaml
analyze-shared:
script:
- npm install
- npx sharity packages/ui --threshold 50
```
## Understanding the Metrics
### Symbol Categories
- **Shared (2+ apps)**: โ
Correctly placed in shared package
- **Exclusive (1 app)**: โ ๏ธ Should likely be moved to that app
- **Unused (0 apps)**: ๐๏ธ Dead code, can be deleted
### Risk Levels
- ๐ด **HIGH** (โฅ70% exclusive): Strong coupling, consider refactoring
- ๐ก **MEDIUM** (40-69% exclusive): Moderate coupling, review
- ๐ข **LOW** (<40% exclusive): Good separation
### When to Worry
**๐จ Red flags:**
- Shared symbol percentage < 30%
- Consumer with >70% exclusive imports
- High unused code percentage (>20%)
**โ
Healthy metrics:**
- Shared symbol percentage > 50%
- Most consumers with <40% exclusive imports
- Unused code < 10%
## Use Cases
### 1. Find Refactoring Opportunities
```bash
# Identify which apps have exclusive imports to extract
npx sharity packages/ui -v
```
### 2. Enforce Architecture Rules
```bash
# Fail CI if sharing drops below 50%
npx sharity packages/ui --threshold 50
```
### 3. Track Progress
```bash
# Before refactoring
npx sharity packages/ui -f json > before.json
# After refactoring
npx sharity packages/ui -f json > after.json
# Compare results
```
### 4. Clean Up Dead Code
```bash
# Find unused exports
npx sharity packages/ui -v | grep "Unused"
```
## How It Works
1. **Scans target package** - Extracts all exported symbols using TypeScript Compiler API
2. **Finds consumer packages** - Uses glob patterns to locate all consumers
3. **Analyzes imports** - Tracks which consumers import which symbols
4. **Calculates metrics** - Determines shared vs exclusive vs unused
5. **Generates report** - Pretty-printed tables or JSON output
## Limitations
- Only analyzes TypeScript/JavaScript files (.ts, .tsx, .js, .jsx)
- Requires static imports (dynamic imports not tracked)
- Line counting excludes comments and empty lines
- Re-exports may be counted multiple times
## Development
```bash
# Clone and install
git clone https://github.com/rayburst/sharity.git
cd sharity
npm install
# Build
npm run build
# Test
npm test
# Lint
npm run lint
```
## Contributing
Contributions welcome! Please:
1. Fork the repo
2. Create a feature branch
3. Add tests
4. Submit a PR
## License
MIT
## Related Tools
- [Knip](https://github.com/webpro/knip) - Find unused files, dependencies, and exports
- [dependency-cruiser](https://github.com/sverweij/dependency-cruiser) - Validate and visualize dependencies
- [ts-unused-exports](https://github.com/pzavolinsky/ts-unused-exports) - Find unused exports in TypeScript
## Why This Tool?
While other tools find unused exports, **sharity** uniquely:
- โ
Calculates **sharing percentages**
- โ
Tracks **per-consumer exclusive imports**
- โ
Provides **architectural insights**
- โ
Supports **CI thresholds**
- โ
Designed for **monorepo workflows**
---
Made with โค๏ธ for better monorepo architecture