npm package: @rayburst/sharity
Description: Analyze shared package usage across monorepos - calculate symbol sharing percentages, track exclusive imports, and identify unused exports
Author: rayburst
Latest version: 0.1.2

# @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