Skip to main content

Overview

GitHub Wrapped is built as a modern Next.js application that transforms GitHub repository data into beautiful, shareable year-in-review visualizations. The architecture follows a clear separation of concerns with distinct layers for data fetching, analytics processing, and presentation.

High-Level Architecture

Data Flow

The application follows a streamlined data pipeline:
1

User Input

Users enter a repository in format owner/repo and select a year through the RepositoryInput component.
2

Validation

The /api/validate endpoint validates the repository exists and is public before proceeding.
3

Cache Check

The system checks Redis (if configured) or in-memory cache for existing wrapped data to avoid redundant API calls.
4

GitHub API Fetching

If no cache exists, GitHubService (lib/github.ts:11) makes parallel requests to GitHub’s REST API using Octokit to fetch:
  • Repository info, contributors, commits
  • Languages, releases, issues, pull requests
  • Stars, forks, and community metrics
5

Analytics Processing

AnalyticsEngine (lib/analytics.ts:24) processes raw GitHub data to calculate:
  • Commit statistics (by month, day, hour)
  • Contributor rankings and activity
  • Language distribution and trends
  • Community growth metrics
  • Monthly activity snapshots
6

Caching

Processed data is cached for 24 hours to improve performance and reduce API usage.
7

Presentation

The WrappedStory component renders 8-12 animated slides using Framer Motion, presenting insights in a Spotify-inspired format.

Component Architecture

Frontend Components

Input Layer

  • RepositoryInput.tsx - Repository search and validation
  • PeriodSelector.tsx - Year/period selection
  • Form validation and error handling

Presentation Layer

  • WrappedStory.tsx - Main story container and navigation
  • WrappedSlide.tsx - Individual slide components (8-12 slides)
  • UserWrappedStory.tsx / UserWrappedSlide.tsx - User-specific wrapped

UI Components

  • Radix UI primitives for accessible components
  • Custom styled components in components/ui/
  • Theme provider for dark/light mode

Layout Components

  • hero.tsx - Landing page hero section
  • theme-toggle.tsx - Theme switching
  • Root layout with metadata and providers

Backend Services

Responsibilities:
  • Octokit client initialization with optional authentication
  • Rate limit checking and management
  • Repository validation and info retrieval
  • Paginated data fetching for commits, contributors, issues, PRs
  • User profile and repository queries
Key Methods:
  • validateRepository() - Checks repo existence and accessibility
  • getCommits() - Fetches commits with date filtering
  • getContributors() - Retrieves contributor statistics
  • getLanguages() - Gets language breakdown
  • getUserRepos() - Fetches user’s repositories
Responsibilities:
  • Transforms raw GitHub data into meaningful insights
  • Calculates aggregated statistics and trends
  • Identifies patterns in commit activity
  • Ranks contributors and languages
  • Generates monthly activity snapshots
Key Methods:
  • generateWrapped() - Main entry point for repository wrapped
  • generateUserWrapped() - Generates user-level wrapped data
  • calculateCommitStats() - Analyzes commit patterns
  • calculateContributorStats() - Ranks top contributors
  • buildMonthlySnapshots() - Creates time-series data
Responsibilities:
  • Dual-layer caching: Redis (production) + in-memory (fallback)
  • 24-hour TTL for wrapped data
  • Validation result caching
  • Automatic expiration and cleanup
Implementation:
  • Uses Upstash Redis when configured
  • Falls back to Map-based in-memory cache
  • Type-safe cache entries with expiration tracking

API Route Organization

The application exposes several API endpoints through Next.js App Router:
RoutePurposeMethod
/api/validateValidate repository existencePOST
/api/wrappedGenerate repository wrappedPOST
/api/wrapped/userGenerate user wrappedPOST
/api/summaryGet quick repository summaryPOST
/api/performancePerformance metrics endpointPOST
/api/ogOpen Graph image generationGET
/api/auth/[...all]Authentication endpoints (better-auth)ALL
/api/user/reposGet authenticated user’s reposGET

Authentication Flow

GitHub Wrapped uses better-auth for authentication:
  1. Users can optionally sign in with GitHub OAuth
  2. Authenticated requests use the user’s GitHub token for higher rate limits
  3. Session management handled by better-auth with PostgreSQL storage
  4. Auth state persisted across requests via secure cookies

Caching Strategy

Production (Redis)

  • Upstash Redis for distributed caching
  • Persistent across deployments
  • Shared cache for all users
  • 24-hour expiration

Development (In-Memory)

  • Map-based in-memory cache
  • Automatic fallback if Redis unavailable
  • Per-process cache (not shared)
  • Same 24-hour expiration

Type Safety

The entire application is built with TypeScript, with comprehensive type definitions in types/index.ts:
  • WrappedData - Repository wrapped data structure
  • UserWrappedData - User-level wrapped data
  • CommitStats - Commit analytics
  • Contributor - Contributor information
  • LanguageStats - Language distribution
  • MonthlySnapshot - Time-series activity data

Performance Optimizations

1

Parallel API Requests

GitHub API calls are batched using Promise.all() to minimize latency.
2

Pagination Limits

Request limits (typically 5-10 pages max) prevent rate limit exhaustion on large repositories.
3

Sampling for Expensive Operations

Line-by-line commit stats are sampled (max 20 commits) to balance detail with performance.
4

Progressive Data Loading

User wrapped limits deep scanning to top 15 most active repositories.
5

Caching

24-hour cache dramatically reduces load on GitHub API and improves response times.

Deployment Architecture

The application is designed for deployment on Vercel:
  • Hosting: Vercel Edge Network
  • Database: PostgreSQL (for auth sessions via Prisma)
  • Cache: Upstash Redis (serverless Redis)
  • CDN: Automatic static asset optimization
  • Environment: Serverless functions for API routes
All API routes run as serverless functions, allowing automatic scaling and geographic distribution.

Build docs developers (and LLMs) love