Comprehensive GitHub Pull Request analytics with contributor insights
A modern, frontend-only React application that provides detailed insights into GitHub repository pull requests, contributor activity, and code metrics.
| Feature | Description |
|---|---|
| π Repository Analytics | Total PRs, merge rates, contributor counts |
| π₯ Contributor Insights | Per-contributor statistics with avatars |
| π Activity Timeline | Daily PR activity visualization |
| π·οΈ Label Distribution | PR labels breakdown |
| πΏ Branch Filtering | Filter PRs by target branch |
| β±οΈ Time Filters | 2 weeks, 1 month, 3 months, 6 months, all time |
| π₯ Export Options | RFC 4180 compliant CSV and JSON data export |
| π Theme Support | Light/dark mode with system preference detect |
| π Web Analytics | Vercel analytics for visitor insights |
flowchart TB
subgraph Client["π Browser Client"]
UI["React UI<br/>(App.tsx)"]
Services["Services Layer"]
Utils["Utilities"]
UI --> Services
Services --> Utils
end
subgraph Services
GH["GitHubService"]
Export["ExportService"]
Storage["StorageService"]
Theme["ThemeService"]
end
subgraph Utils
DateUtils["DateUtils"]
URLParser["URLParser"]
end
subgraph External["βοΈ External"]
GitHubAPI["GitHub REST API v3"]
LocalStorage["localStorage"]
end
GH <-->|"HTTPS"| GitHubAPI
Storage <--> LocalStorage
Theme <--> LocalStorage
frontend/
βββ src/
β βββ components/ # React UI components
β β βββ common/ # Shared: Loader, Toast, ErrorBoundary
β β βββ contributors/ # ContributorCard, ContributorList, Modal
β β βββ layout/ # Header, Footer, Sidebar
β β βββ repository/ # RepositoryStats display
β β
β βββ services/ # Business logic layer
β β βββ GitHubService.ts # GitHub API integration
β β βββ ExportService.ts # CSV/JSON file exports
β β βββ StorageService.ts# Bookmarks & history
β β βββ ThemeService.ts # Dark/light mode
β β
β βββ utils/ # Utility functions
β β βββ dateUtils.ts # Date manipulation
β β βββ urlParser.ts # GitHub URL parsing (supports multiple formats)
β β
β βββ constants/ # Centralized configuration
β β βββ index.ts
β β
β βββ types/ # TypeScript interfaces
β β βββ index.ts
β β
β βββ styles/ # CSS styles
β β βββ index.css
β β
β βββ App.tsx # Main application component
β
βββ public/ # Static assets
βββ index.html # HTML entry point
βββ package.json
βββ vite.config.ts
βββ tsconfig.json
sequenceDiagram
participant User
participant App
participant GitHubService
participant GitHub API
participant ExportService
User->>App: Enter repository URL
App->>GitHubService: fetchRepositoryStats()
GitHubService->>GitHub API: GET /repos/{owner}/{repo}/pulls
GitHub API-->>GitHubService: Pull requests data
GitHubService->>GitHubService: Calculate statistics
GitHubService-->>App: RepositoryStats
App->>App: Render charts & contributors
User->>App: Click "Export CSV"
App->>ExportService: exportRepositoryCsv(stats)
ExportService->>ExportService: Generate CSV blob
ExportService-->>User: Download file
- Node.js 18+
- npm or yarn
# Clone the repository
git clone https://github.com/your-username/pr-analyzer.git
cd pr-analyzer/frontend
# Install dependencies
npm install
# Start development server
npm run dev# Build and run with Docker Compose
docker compose up --build -d
# Access at http://localhost:5173For higher rate limits (5,000/hour vs 60/hour), add a GitHub Personal Access Token:
- Go to GitHub Settings β Tokens
- Generate a new token (no scopes needed for public repos)
- Enter the token in the app's token input section
π The token is stored in your browser's localStorage, never sent to any server.
The URL parser supports multiple GitHub URL formats:
| Format | Example |
|---|---|
| Simple | facebook/react |
| Domain | github.com/owner/repo |
| Full URL | https://github.com/owner/repo |
| With .git | https://github.com/owner/repo.git |
| SSH | [email protected]:owner/repo.git |
| PR URLs | https://github.com/owner/repo/pull/123 |
import { GitHubUrlParser, extractPRNumber } from "./utils";
// Parse any format
GitHubUrlParser.parse("[email protected]:facebook/react.git");
// β { owner: 'facebook', repo: 'react' }
// Extract PR number from URL
extractPRNumber("https://github.com/owner/repo/pull/456");
// β 456| Auth Status | Rate Limit | Best For |
|---|---|---|
| Without Token | 60/hour | Quick lookups |
| With Token | 5,000/hour | Heavy analysis |
graph TD
App["App"]
App --> Hero["Hero Section"]
App --> Results["Results View"]
App --> Toast["ToastContainer"]
Hero --> SearchForm["Search Form"]
Hero --> TokenInput["Token Input"]
Results --> RepoStats["RepositoryStats"]
Results --> ContribList["ContributorList"]
Results --> Modal["ContributorModal"]
ContribList --> Card1["ContributorCard"]
ContribList --> Card2["ContributorCard"]
ContribList --> CardN["..."]
RepoStats --> StatCards["Stat Cards"]
RepoStats --> Labels["Label Distribution"]
RepoStats --> Timeline["Activity Timeline"]
| Layer | Technology |
|---|---|
| Framework | React 18 with TypeScript |
| Build Tool | Vite |
| Styling | Vanilla CSS with CSS Variables |
| Icons | Lucide React |
| API | GitHub REST API v3 |
| Storage | Browser localStorage |
| Analytics | Vercel Web Analytics |
npm run dev # Start development server
npm run build # Build for production
npm run preview # Preview production build
npm run lint # Run ESLint- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is open source and available under the MIT License.
Made with β€οΈ for the open source community