@rayburst/sharity
v0.1.2
Published
Analyze shared package usage across monorepos - calculate symbol sharing percentages, track exclusive imports, and identify unused exports
Maintainers
Readme
@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)
pnpm add -D @rayburst/sharity
# or
npm install --save-dev @rayburst/sharity
# or
yarn add -D @rayburst/sharityGlobal installation
npm install -g @rayburst/sharityQuick Start
CLI Usage
# 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 50As npm script
Add to your package.json:
{
"scripts": {
"analyze:ui": "sharity packages/ui --consumers 'apps/*' 'packages/*'",
"analyze:ui:ci": "sharity packages/ui --threshold 50"
}
}Then run:
npm run analyze:uiProgrammatic API
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 commandExample 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:
{
"packagePath": "./packages/ui",
"consumerGlobs": ["apps/*", "packages/*"],
"excludePatterns": ["**/*.test.ts", "**/__mocks__/**"],
"includeTests": false,
"sharingThreshold": 50,
"outputFormat": "table",
"verbose": false
}Then use it:
npx sharity --config .sharity.jsonCI/CD Integration
GitHub Actions
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 50GitLab CI
analyze-shared:
script:
- npm install
- npx sharity packages/ui --threshold 50Understanding 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
# Identify which apps have exclusive imports to extract
npx sharity packages/ui -v2. Enforce Architecture Rules
# Fail CI if sharing drops below 50%
npx sharity packages/ui --threshold 503. Track Progress
# Before refactoring
npx sharity packages/ui -f json > before.json
# After refactoring
npx sharity packages/ui -f json > after.json
# Compare results4. Clean Up Dead Code
# Find unused exports
npx sharity packages/ui -v | grep "Unused"How It Works
- Scans target package - Extracts all exported symbols using TypeScript Compiler API
- Finds consumer packages - Uses glob patterns to locate all consumers
- Analyzes imports - Tracks which consumers import which symbols
- Calculates metrics - Determines shared vs exclusive vs unused
- 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
# 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 lintContributing
Contributions welcome! Please:
- Fork the repo
- Create a feature branch
- Add tests
- Submit a PR
License
MIT
Related Tools
- Knip - Find unused files, dependencies, and exports
- dependency-cruiser - Validate and visualize dependencies
- 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
