CLI to compute contributor and repository statistics from a Git repository (commits, lines added/deleted, frequency, heatmap, bus-factor), with filters and multiple output formats.
npm install git-contributor-statsA powerful, fast Node.js CLI and library to analyze Git repository contributions with detailed statistics, charts, and multiple output formats.



---
> π¦ Modular & Tree-Shakeable
>
> This package uses subpath exports for optimal bundle sizes. Import only what you need:
> - git-contributor-stats/stats - Core statistics
> - git-contributor-stats/charts - Chart generation
> - git-contributor-stats/reports - Report generation
> - git-contributor-stats/output - Console output
> - git-contributor-stats/workflow - GitHub Actions workflow
>
> See Technical Docs for architecture details and Quick Start for usage examples.
---
Analyze your Git repository to gain insights into contributor activity, code ownership, commit patterns, and project health. Get comprehensive statistics including commits, lines added/deleted, file changes, temporal patterns, bus factor analysis, and beautiful visualizations.
Requirements: Node.js 18+ (ESM-only)
- Features
- Installation
- Quick Start
- CLI Usage
- Basic Commands
- Filtering Options
- Output Formats
- Charts & Visualizations
- Report Customization
- Programmatic API
- Identity Management
- Configuration
- Examples
- Output Reference
- Performance Tips
- Documentation
- Contributing
- License
90.days, 2.weeks, etc.)``bash`
npm install -g git-contributor-stats
`bash`
npm install git-contributor-stats
> π‘ New to this tool? See Quick Start Guide for detailed use cases and examples
`bashAnalyze current repository
git-contributor-stats
$3
`javascript
// Import only what you need using subpath exports
import { getContributorStats } from 'git-contributor-stats/stats';const stats = await getContributorStats({
repo: '.',
since: '90.days',
countLines: false
});
console.log(
Total commits: ${stats.totalCommits});
console.log(Top contributor: ${stats.topContributors[0].name});
`CLI Usage
$3
`bash
git-contributor-stats [options] [paths...]
`Arguments:
-
[paths...] - Optional pathspec(s) to limit analysis to certain files/directories$3
`bash
Show help
git-contributor-stats --helpShow version
git-contributor-stats --versionAnalyze current repository (default: table output)
git-contributor-statsAnalyze specific repository
git-contributor-stats --repo /path/to/repoAnalyze specific paths only
git-contributor-stats src/ lib/
`$3
#### Repository & Branch
| Option | Description | Example |
|--------|-------------|---------|
|
-r, --repo | Path to Git repository | --repo /path/to/repo |
| -b, --branch | Branch or commit range | --branch main or --branch main..feature |#### Time-Based Filtering
| Option | Description | Example |
|--------|-------------|---------|
|
--since | Only commits after date | --since 2024-01-01 or --since 90.days |
| --until | Only commits before date | --until 2024-12-31 or --until 1.week |Supported relative time formats:
- Days:
30.days, 1.day
- Weeks: 2.weeks, 1.week
- Months: 3.months, 1.month
- Years: 1.year, 2.yearsExample:
`bash
Last quarter
git-contributor-stats --since 90.daysSpecific date range
git-contributor-stats --since 2024-01-01 --until 2024-06-30Last 2 weeks on main branch
git-contributor-stats -b main --since 2.weeks
`#### Author & Merge Filtering
| Option | Description | Example |
|--------|-------------|---------|
|
-a, --author | Filter by author (string/regex) | --author "John" |
| --include-merges | Include merge commits | --include-merges |Example:
`bash
Contributions from specific author
git-contributor-stats --author "jane@example.com"Include merge commits (excluded by default)
git-contributor-stats --include-merges
`$3
| Option | Description | Default | Values |
|--------|-------------|---------|--------|
|
-g, --group-by | Group contributors by | email | email, name |
| -s, --sort-by | Sort contributors by | changes | changes, commits, additions, deletions |
| -t, --top | Limit to top N contributors | All | Any number |Example:
`bash
Group by name instead of email
git-contributor-stats --group-by nameSort by commit count, show top 15
git-contributor-stats --sort-by commits --top 15Sort by net lines added
git-contributor-stats --sort-by additions --top 10
`$3
#### Standard Output (stdout)
| Option | Description | Output |
|--------|-------------|--------|
|
-f, --format | Format for stdout | table, json, csv |
| --json | Comprehensive JSON analysis | Full analysis object |Example:
`bash
Table output (default)
git-contributor-statsJSON to stdout
git-contributor-stats --jsonCSV to stdout
git-contributor-stats --format csvCompact table with top 10
git-contributor-stats --format table --top 10
`#### File Outputs
| Option | Description |
|--------|-------------|
|
--csv | Write CSV report to file |
| --md | Write Markdown report to file |
| --html | Write HTML dashboard to file |
| --out-dir | Directory for all outputs (uses default names) |Example:
`bash
Individual file outputs
git-contributor-stats --csv stats.csv --md report.md --html dashboard.htmlUse output directory (creates contributors.csv, report.md, report.html)
git-contributor-stats --out-dir reportsCombine with specific names
git-contributor-stats --out-dir reports --md reports/custom-report.md
`$3
#### Chart Generation
| Option | Description | Default |
|--------|-------------|---------|
|
--charts | Generate charts | Disabled |
| --charts-dir | Directory for charts | ./charts or --out-dir |
| --chart-format | Chart format | svg |Chart formats:
-
svg - Scalable Vector Graphics (recommended)
- png - Portable Network Graphics
- both - Generate both SVG and PNGGenerated charts:
1.
top-commits.svg/png - Bar chart of top contributors by commit count
2. top-net.svg/png - Bar chart of top contributors by net lines
3. heatmap.svg/png - Activity heatmap (weekday Γ hour)Example:
`bash
Generate SVG charts in default location
git-contributor-stats --chartsGenerate PNG charts
git-contributor-stats --charts --chart-format pngGenerate both formats in custom directory
git-contributor-stats --charts --charts-dir ./output/charts --chart-format bothCharts with reports
git-contributor-stats --out-dir reports --md --html --charts
`$3
#### Top Stats Configuration
Control which metrics appear in the "Top Stats" section of reports and stdout:
| Option | Description | Default |
|--------|-------------|---------|
|
--top-stats | Comma-separated metrics to show | All metrics |
| --no-top-stats | Omit Top Stats section entirely | Enabled |Available metrics:
-
commits - Most commits
- additions - Most lines added
- deletions - Most lines deleted
- net - Best net contribution (additions - deletions)
- changes - Most total changes (additions + deletions)Example:
`bash
Show only commits and net in Top Stats
git-contributor-stats --top-stats commits,net --md report.mdOmit Top Stats entirely (faster, cleaner output)
git-contributor-stats --no-top-stats --html dashboard.htmlDefault: all metrics shown
git-contributor-stats --md report.md
`$3
| Option | Description |
|--------|-------------|
|
--alias-file | Path to alias mapping JSON |
| --similarity <0..1> | Name merge similarity threshold (default: 0.85) |Example:
`bash
Use custom alias file
git-contributor-stats --alias-file config/aliases.jsonAdjust similarity threshold (higher = stricter matching)
git-contributor-stats --similarity 0.9Combine with reports
git-contributor-stats --alias-file aliases.json --out-dir reports --md --html
`See Identity Management section for alias file format.
$3
| Option | Description | Impact |
|--------|-------------|--------|
|
--no-count-lines | Skip total LOC counting | Faster analysis |Example:
`bash
Skip LOC counting for large repos (significant speed improvement)
git-contributor-stats --no-count-lines --jsonFast report generation
git-contributor-stats --out-dir reports --md --html --no-count-lines
`$3
| Option | Description |
|--------|-------------|
|
--generate-workflow | Create GitHub Actions workflow file |
| -v, --verbose | Enable verbose logging (stderr) |Example:
`bash
Generate GitHub Actions workflow
git-contributor-stats --generate-workflowDebug mode
git-contributor-stats --verbose --jsonSee what git commands are being run
git-contributor-stats -v --since 30.days
`Programmatic API
Use
git-contributor-stats as a library in your Node.js/TypeScript projects.$3
`javascript
import { getContributorStats } from 'git-contributor-stats/stats';// Analyze current repository
const stats = await getContributorStats({
repo: '.',
since: '90.days',
countLines: false
});
console.log(
Total commits: ${stats.totalCommits});
console.log(Contributors: ${Object.keys(stats.contributors).length});
console.log(Top contributor: ${stats.topContributors[0].name});
`$3
####
getContributorStats(options)Returns a Promise that resolves to a comprehensive analysis object.
Options:
`typescript
interface ContributorStatsOptions {
// Repository options
repo?: string; // Path to repository (default: '.')
branch?: string; // Branch or range (e.g., 'main..feature')
paths?: string | string[]; // Pathspec(s) to limit analysis
// Filtering options
since?: string; // Date or relative time (e.g., '90.days')
until?: string; // Date or relative time
author?: string; // Author pattern (string/regex)
includeMerges?: boolean; // Include merge commits (default: false)
// Grouping & sorting
groupBy?: 'email' | 'name'; // Group by field (default: 'email')
labelBy?: 'email' | 'name'; // Display label (default: 'name')
sortBy?: 'changes' | 'commits' | 'additions' | 'deletions';
top?: number; // Limit to top N contributors
// Identity management
similarity?: number; // Name merge threshold (default: 0.85)
aliasFile?: string; // Path to alias JSON file
aliasConfig?: AliasConfig; // Inline alias configuration
// Performance
countLines?: boolean; // Count total LOC (default: true)
verbose?: boolean; // Enable verbose logging (default: false)
}
`Return Value:
`typescript
interface ContributorStatsResult {
meta: {
generatedAt: string; // ISO timestamp
repo: string; // Repository path
branch: string | null; // Branch name
since: string | null; // Since date/time
until: string | null; // Until date/time
};
totalCommits: number; // Total commit count
totalLines: number; // Total lines of code
contributors: Record;
topContributors: TopContributor[];
topStats: {
byCommits: TopContributor | null;
byAdditions: TopContributor | null;
byDeletions: TopContributor | null;
byNet: TopContributor | null;
byChanges: TopContributor | null;
};
commitFrequency: {
monthly: Record;
weekly: Record;
};
heatmap: number[][]; // 7x24 grid (weekday x hour)
busFactor: {
filesSingleOwner: Array<{
file: string;
owner: string;
changes: number;
}>;
};
basic: {
contributors: TopContributor[];
meta: ContributorsMeta;
groupBy: 'email' | 'name';
};
}
`$3
#### Analyze Specific Time Period
`javascript
import { getContributorStats } from 'git-contributor-stats/stats';const stats = await getContributorStats({
repo: '/path/to/repo',
since: '2024-01-01',
until: '2024-06-30',
branch: 'main'
});
console.log('Q1-Q2 2024 Stats:');
console.log(
- Commits: ${stats.totalCommits});
console.log(- Active contributors: ${stats.topContributors.length});
`#### Filter by Author and Path
`javascript
import { getContributorStats } from 'git-contributor-stats/stats';const stats = await getContributorStats({
repo: '.',
author: 'jane@example.com',
paths: ['src/', 'lib/'],
since: '30.days'
});
console.log(
Jane's contributions in src/ and lib/ (last 30 days):);
console.log(- Commits: ${stats.topContributors[0]?.commits || 0});
console.log(- Files changed: ${Object.keys(stats.topContributors[0]?.files || {}).length});
`#### Generate Reports Programmatically
`javascript
import { getContributorStats } from 'git-contributor-stats/stats';
import { generateReports } from 'git-contributor-stats/reports';const stats = await getContributorStats({
repo: '.',
since: '90.days',
countLines: false
});
// Generate reports
await generateReports(stats, {
outDir: 'reports',
md: 'reports/quarterly-report.md',
html: 'reports/quarterly-report.html',
csv: 'reports/contributors.csv'
});
console.log('Reports generated in ./reports/');
`#### Generate Charts Programmatically
`javascript
import { getContributorStats } from 'git-contributor-stats/stats';
import { generateCharts } from 'git-contributor-stats/charts';const stats = await getContributorStats({
repo: '.',
since: '90.days'
});
// Generate SVG charts
await generateCharts(stats, {
charts: true,
chartsDir: 'output/charts',
chartFormat: 'svg'
});
// Or PNG charts
await generateCharts(stats, {
charts: true,
chartsDir: 'output/charts',
chartFormat: 'png'
});
// Or both
await generateCharts(stats, {
charts: true,
chartsDir: 'output/charts',
chartFormat: 'both'
});
`#### Using Alias Configuration Inline
`javascript
import { getContributorStats } from 'git-contributor-stats/stats';const stats = await getContributorStats({
repo: '.',
aliasConfig: {
groups: [
['jane@example.com', 'jane.doe@example.com', 'Jane Doe'],
['john@example.com', 'john.smith@example.com']
],
canonical: {
'jane@example.com': {
name: 'Jane Doe',
email: 'jane@example.com'
},
'john@example.com': {
name: 'John Smith',
email: 'john@example.com'
}
}
},
similarity: 0.9
});
`#### Custom Analysis and Reporting
`javascript
import { getContributorStats } from 'git-contributor-stats/stats';const stats = await getContributorStats({
repo: '.',
since: '1.year',
groupBy: 'name',
sortBy: 'commits'
});
// Custom analysis
const topContributor = stats.topContributors[0];
const busFactorFiles = stats.busFactor.filesSingleOwner.length;
const avgCommitsPerMonth = stats.totalCommits / 12;
console.log('Annual Report:');
console.log(
Top contributor: ${topContributor.name});
console.log(- Commits: ${topContributor.commits});
console.log(- Net lines: ${topContributor.net});
console.log(\nRisk Analysis:);
console.log(- Single-owner files: ${busFactorFiles});
console.log(- Avg commits/month: ${avgCommitsPerMonth.toFixed(1)});// Access monthly breakdown
const monthlyActivity = stats.commitFrequency.monthly;
console.log('\nMonthly Activity:');
Object.entries(monthlyActivity)
.sort(([a], [b]) => a.localeCompare(b))
.forEach(([month, commits]) => {
console.log(
${month}: ${commits} commits);
});
`#### TypeScript Support
Full TypeScript definitions are included:
`typescript
import type {
ContributorStatsOptions,
ContributorStatsResult,
TopContributor,
TopStatsSummary,
BusFactorInfo
} from 'git-contributor-stats/stats';
import { getContributorStats } from 'git-contributor-stats/stats';const options: ContributorStatsOptions = {
repo: '.',
since: '90.days',
countLines: false
};
const stats: ContributorStatsResult = await getContributorStats(options);
// Type-safe access
const topContributor: TopContributor = stats.topContributors[0];
const busFactor: BusFactorInfo = stats.busFactor;
`$3
`typescript
// From 'git-contributor-stats/stats'
export async function getContributorStats(
options?: ContributorStatsOptions
): Promise// From 'git-contributor-stats/reports'
export async function generateReports(
stats: ContributorStatsResult,
options?: ReportOptions
): Promise
// From 'git-contributor-stats/charts'
export async function generateCharts(
stats: ContributorStatsResult,
options?: ChartOptions,
outDir?: string
): Promise
// From 'git-contributor-stats/output'
export function handleStdoutOutput(
stats: ContributorStatsResult,
options?: OutputOptions
): void
// From 'git-contributor-stats/workflow'
export async function generateWorkflow(repo: string): Promise
`Identity Management
Consolidate multiple emails and names for the same person using alias mapping.
$3
The tool automatically looks for
.git-contributor-stats-aliases.json in the repository root.$3
`bash
Use default file (if exists)
git-contributor-statsUse custom file
git-contributor-stats --alias-file config/aliases.json
`$3
#### Format 1: Simple Map
Map aliases to canonical identities:
`json
{
"jane@example.com": "jane.doe@example.com",
"Jane Doe": "jane.doe@example.com",
"john@example.com": "john.smith@example.com",
"J. Smith": "john.smith@example.com"
}
`#### Format 2: Extended Configuration
More control with groups and canonical details:
`json
{
"map": {
"jane@old-company.com": "jane.doe@example.com",
"jdoe@example.com": "jane.doe@example.com"
},
"groups": [
["john@example.com", "jsmith@example.com", "john.smith@example.com"],
["alice@example.com", "alice.dev@example.com"]
],
"canonical": {
"jane.doe@example.com": {
"name": "Jane Doe",
"email": "jane.doe@example.com"
},
"john.smith@example.com": {
"name": "John Smith",
"email": "john.smith@example.com"
}
}
}
`#### Format 3: Array of Groups
Shorthand for groups:
`json
[
["jane@example.com", "jane.doe@example.com", "Jane Doe"],
["john@example.com", "john.smith@example.com", "John Smith"],
["alice@old.com", "alice@new.com", "alice@example.com"]
]
`$3
Use regex patterns for flexible matching:
`json
{
"map": {
"/^jane\\.doe@.+$/i": "jane.doe@example.com",
"/^(John Smith|J\\.? Smith)$/": "john.smith@example.com"
}
}
`Pattern format: Strings starting and ending with
/ are treated as regex patterns.$3
Control automatic name merging:
`bash
Default threshold (0.85)
git-contributor-statsStricter matching (higher threshold)
git-contributor-stats --similarity 0.95More permissive (lower threshold)
git-contributor-stats --similarity 0.75
`Range: 0.0 (merge everything) to 1.0 (exact match only)
Recommended: 0.80 - 0.90
Configuration
$3
Currently, the tool uses command-line options and alias files. Environment variables are not used.
$3
| Setting | Default | Description |
|---------|---------|-------------|
| Repository | Current directory (
.) | Can override with --repo |
| Output format | table | Can change with --format |
| Group by | email | Can change with --group-by |
| Sort by | changes | Can change with --sort-by |
| Similarity | 0.85 | Can change with --similarity |
| Count lines | true | Disable with --no-count-lines |
| Include merges | false | Enable with --include-merges |
| Top stats | true | Disable with --no-top-stats |Examples
$3
#### 1. Quarterly Report Generation
`bash
Generate comprehensive quarterly report with all outputs
git-contributor-stats \
--since 90.days \
--out-dir reports/q4-2024 \
--md reports/q4-2024/report.md \
--html reports/q4-2024/dashboard.html \
--csv reports/q4-2024/contributors.csv \
--charts \
--chart-format both \
--no-count-lines
`#### 2. Team-Specific Analysis
`bash
Analyze backend team contributions in src/backend/
git-contributor-stats \
src/backend/ \
--since 1.year \
--alias-file config/team-aliases.json \
--out-dir reports/backend-team \
--md --html \
--charts \
--top-stats commits,net
`#### 3. Release Analysis
`bash
Compare two releases
git-contributor-stats \
--branch v1.0.0..v2.0.0 \
--json > v1-to-v2-stats.jsonAnalyze specific release period
git-contributor-stats \
--since 2024-01-01 \
--until 2024-03-31 \
--out-dir reports/v2.0 \
--md --html --charts
`#### 4. Performance-Optimized Analysis
`bash
Fast analysis for large repos
git-contributor-stats \
--no-count-lines \
--since 6.months \
--top 20 \
--format table
`#### 5. Custom Top Stats
`bash
Only show commits and net contribution
git-contributor-stats \
--top-stats commits,net \
--out-dir reports \
--md reports/simple-report.md
`#### 6. CI/CD Integration
`bash
Generate GitHub Actions workflow
git-contributor-stats --generate-workflowRun in CI (example)
git-contributor-stats \
--since 7.days \
--out-dir artifacts \
--md artifacts/weekly-report.md \
--charts \
--no-count-lines
`$3
#### Monitor Repository Health
`javascript
import { getContributorStats } from 'git-contributor-stats/stats';async function checkRepoHealth() {
const stats = await getContributorStats({
repo: '.',
since: '90.days'
});
const activeDevelopers = stats.topContributors.length;
const singleOwnerFiles = stats.busFactor.filesSingleOwner.length;
const totalFiles = Object.keys(
stats.topContributors.reduce((acc, c) => ({ ...acc, ...c.files }), {})
).length;
const busFactorRisk = singleOwnerFiles / totalFiles;
console.log('Repository Health Check:');
console.log(
Active developers (90d): ${activeDevelopers});
console.log(Bus factor risk: ${(busFactorRisk * 100).toFixed(1)}%);
if (busFactorRisk > 0.3) {
console.warn('β οΈ High bus factor risk - consider knowledge sharing');
}
if (activeDevelopers < 3) {
console.warn('β οΈ Low active developer count');
}
}import { generateReports } from 'git-contributor-stats/reports';
import { generateCharts } from 'git-contributor-stats/charts';
`#### Generate Custom Dashboard
`javascript
import { getContributorStats } from 'git-contributor-stats/stats';
import { generateReports } from 'git-contributor-stats/reports';
import { generateCharts } from 'git-contributor-stats/charts';async function generateDashboard() {
const [weekly, monthly, quarterly] = await Promise.all([
getContributorStats({ since: '7.days' }),
getContributorStats({ since: '30.days' }),
getContributorStats({ since: '90.days' })
]);
await generateReports(weekly, {
outDir: 'dashboard/weekly',
md: 'dashboard/weekly/report.md',
html: 'dashboard/weekly/report.html'
});
await generateReports(monthly, {
outDir: 'dashboard/monthly',
md: 'dashboard/monthly/report.md',
html: 'dashboard/monthly/report.html'
});
await generateCharts(monthly, {
charts: true,
chartsDir: 'dashboard/monthly/charts'
});
await generateReports(quarterly, {
outDir: 'dashboard/quarterly',
md: 'dashboard/quarterly/report.md',
html: 'dashboard/quarterly/report.html'
});
await generateCharts(quarterly, {
charts: true,
chartsDir: 'dashboard/quarterly/charts',
chartFormat: 'both'
});
console.log('β Multi-period dashboard generated');
}
generateDashboard();
`Output Reference
$3
`
Top stats:
- Most commits: John Smith (234)
- Most additions: Jane Doe (15,432)
- Most deletions: Alice Dev (8,901)
- Best net contribution: Jane Doe (12,345)
- Most changes: Jane Doe (24,333)βββββββ¬βββββββββββββββββ¬ββββββββββ¬βββββββββββ¬βββββββββββ¬ββββββββββ
βRank β Contributor β Commits β Additionsβ Deletionsβ Changes β
βββββββΌβββββββββββββββββΌββββββββββΌβββββββββββΌβββββββββββΌββββββββββ€
β 1 β Jane Doe β 156 β 15,432 β 3,087 β 18,519 β
β 2 β John Smith β 234 β 8,901 β 4,523 β 13,424 β
β 3 β Alice Dev β 145 β 6,234 β 8,901 β 15,135 β
βββββββ΄βββββββββββββββββ΄ββββββββββ΄βββββββββββ΄βββββββββββ΄ββββββββββ
`$3
Comprehensive analysis object with all metrics (see API Reference).
$3
`csv
Rank,Name,Email,Commits,Additions,Deletions,Net,Changes
1,Jane Doe,jane@example.com,156,15432,3087,12345,18519
2,John Smith,john@example.com,234,8901,4523,4378,13424
3,Alice Dev,alice@example.com,145,6234,8901,-2667,15135
`$3
- Summary statistics
- Top stats (configurable)
- Top contributors table with file details
- Bus factor analysis
- Activity patterns (monthly breakdown, heatmap data)
$3
Interactive HTML report with:
- Styled summary cards
- Sortable contributor table
- Bus factor risk indicators
- Embedded charts (if generated)
- Monthly/weekly activity visualization
Performance Tips
$3
`bash
Skip LOC counting (significant speedup)
git-contributor-stats --no-count-linesLimit time range
git-contributor-stats --since 6.monthsLimit to specific paths
git-contributor-stats src/ --no-count-lines
`$3
`bash
Analyze only recent commits
git-contributor-stats --since 30.days --top 10Specific branch only
git-contributor-stats -b main --since 90.daysExclude merge commits (default, but explicit)
git-contributor-stats --no-include-merges
`$3
`bash
Fast CI run
git-contributor-stats \
--since 7.days \
--no-count-lines \
--format json > stats.json
`$3
Typical performance on a medium-sized repository (10k commits):
| Operation | With
--count-lines | With --no-count-lines |
|-----------|---------------------|------------------------|
| Full analysis | ~15-20s | ~3-5s |
| Last 90 days | ~8-12s | ~2-3s |
| Last 30 days | ~5-8s | ~1-2s |Performance varies based on repository size, file count, and system resources.
Development
$3
`bash
git clone https://github.com/vikkrantxx7/git-contributor-stats.git
cd git-contributor-stats
npm install
`$3
`bash
Build the project
npm run buildRun tests
npm testRun linter
npm run biomeFix linting issues
npm run biome:fixGenerate types
npm run build:typesDevelopment mode (uses source files)
node dist/cli.mjs --helpGenerate sample reports
npm run report
`$3
`
git-contributor-stats/
βββ src/
β βββ features/
β β βββ stats.ts # Core statistics (tree-shakeable)
β β βββ charts.ts # Chart generation (tree-shakeable)
β β βββ reports.ts # Report generation (tree-shakeable)
β β βββ output.ts # Console output (tree-shakeable)
β β βββ workflow.ts # GitHub Actions workflow (tree-shakeable)
β βββ cli/
β β βββ entry.ts # CLI entry point
β β βββ index.ts # CLI logic
β β βββ options.ts # Command-line options
β βββ analytics/
β β βββ aggregator.ts # Data aggregation
β β βββ aliases.ts # Identity resolution
β β βββ analyzer.ts # Core analysis logic
β βββ charts/
β β βββ renderer.ts # Chart rendering (PNG)
β β βββ svg.ts # SVG generation
β βββ git/
β β βββ parser.ts # Git log parsing
β β βββ utils.ts # Git operations
β βββ reports/
β β βββ csv.ts # CSV generation
β β βββ html.ts # HTML generation
β β βββ markdown.ts # Markdown generation
β βββ utils/
β β βββ dates.ts # Date parsing
β β βββ files.ts # File operations
β β βββ formatting.ts # Output formatting
β βββ api.ts # TypeScript types
βββ dist/ # Built files
β βββ features/ # Feature modules (separate entry points)
β βββ chunks/ # Shared code chunks
βββ tests/ # Test files
βββ package.json
βββ tsconfig.json
βββ vite.config.ts
βββ vitest.config.ts
`-
git-contributor-stats/charts - Chart generation with Chart.js (~260KB with charts)
- git-contributor-stats/reports - Report generation: CSV, Markdown, HTML (~200KB)
- git-contributor-stats/output - Console output formatting (table, JSON, CSV)
- git-contributor-stats/workflow - GitHub Actions workflow generator (~5KB)
- git-contributor-stats/cli - CLI entry point (combines all features)Bundle Size Comparison:
| Import | Bundle Size | Reduction |
|---------|---------|-------------|
| Core stats only | ~80KB | 84% smaller |
| Stats + Reports | ~200KB | 60% smaller |
| Stats + Charts | ~260KB | 48% smaller |
| Full features (CLI) | ~400KB | 20% smaller |
Compared to the previous monolithic bundle of ~500KB
See Technical Documentation for architecture details, tree-shaking verification, and migration guide
$3
`bash
Run all tests
npm testRun specific test
npm test -- tests/e2e/api.test.tsWatch mode
npm test -- --watchCoverage
npm test -- --coverage
`Documentation
docs/ directory:- Quick Start Guide - Get started in 30 seconds with common use cases
- Quick Reference - Command cheat sheet for quick lookup
- Contributing Guide - How to contribute to this project
- Commit Guidelines - Conventional commits format
- Release Workflow - Version management with changesets
- Technical Documentation - Architecture and internals
Contributing
We welcome contributions! Please see our Contributing Guide for details.
Quick steps:
1. Fork the repository
2. Create a feature branch (
git checkout -b feature/amazing-feature)
3. Make your changes
4. Run tests and linter (npm test && npm run lint)
5. Commit following conventional commits (git commit -m 'feat: add amazing feature')
6. Add a changeset (npx changeset)
7. Push and open a Pull Request> π This project uses Conventional Commits and Changesets for version management.
GitHub Actions Integration
Generate a workflow file:
`bash
git-contributor-stats --generate-workflow
`This creates
.github/workflows/git-contributor-stats.yml:`yaml
name: Git Contributor Statson:
schedule:
- cron: '0 0 0' # Weekly on Sunday
workflow_dispatch:
jobs:
stats:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install git-contributor-stats
run: npm install -g git-contributor-stats
- name: Generate reports
run: |
git-contributor-stats \
--since 90.days \
--out-dir reports \
--md reports/report.md \
--html reports/report.html \
--charts \
--no-count-lines
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: contributor-stats
path: reports/
``π This project publishes packages with NPM provenance enabled, providing cryptographic proof of build authenticity.
For security issues, please see SECURITY.md for our security policy and how to report vulnerabilities responsibly.
MIT License - see LICENSE file for details.
- npm Package
- GitHub Repository
- Issue Tracker
- Security Policy
---
Made with β€οΈ for better repository insights