Skip to main content

Directory Overview

GitHub Wrapped follows Next.js 16 App Router conventions with a clean separation between pages, components, and business logic.
github-wrapped/
├── app/                      # Next.js App Router pages and API routes
│   ├── api/                  # Backend API endpoints
│   ├── wrapped/              # Wrapped story pages
│   ├── layout.tsx            # Root layout with providers
│   ├── page.tsx              # Homepage
│   └── opengraph-image.tsx   # OG image generator
├── components/               # React components
│   ├── ui/                   # Reusable UI primitives
│   ├── RepositoryInput.tsx   # Main input form
│   ├── WrappedStory.tsx      # Story container
│   ├── WrappedSlide.tsx      # Slide components
│   └── ...
├── lib/                      # Business logic and utilities
│   ├── github.ts             # GitHub API service
│   ├── analytics.ts          # Analytics engine
│   ├── cache.ts              # Caching layer
│   ├── auth.ts               # Authentication config
│   └── utils.ts              # Helper functions
├── types/                    # TypeScript type definitions
│   └── index.ts              # Shared types
├── hooks/                    # Custom React hooks
├── public/                   # Static assets
├── prisma/                   # Database schema (if present)
├── .env.local                # Environment variables (not in git)
├── next.config.ts            # Next.js configuration
├── tailwind.config.ts        # Tailwind CSS configuration
├── tsconfig.json             # TypeScript configuration
├── package.json              # Dependencies and scripts
└── README.md                 # Project documentation

App Directory (/app)

The app/ directory contains all routes using Next.js App Router.

API Routes (/app/api)

Serverless API endpoints for backend functionality:
Purpose: better-auth catch-all authentication routeHandles all authentication flows:
  • GitHub OAuth login/logout
  • Session management
  • Token refresh
Purpose: Generate repository wrapped dataRequest:
{ "owner": "facebook", "repo": "react", "year": 2024 }
Response: Complete WrappedData objectFlow:
  1. Check cache
  2. Validate repository
  3. Fetch GitHub data
  4. Run analytics
  5. Cache and return
Purpose: Generate user-level wrapped (“My Year in Code”)Request:
{ "username": "octocat", "year": 2024 }
Response: UserWrappedData with personal stats
Purpose: Quick repository validationChecks if a repository exists and is public before generating wrapped.
Purpose: Quick repository summary for previewsReturns basic info without full analytics.
Purpose: Dynamic Open Graph image generationGenerates custom social sharing images with Vercel OG.
Purpose: Performance metrics and monitoringInternal endpoint for tracking API performance.
Purpose: Get authenticated user’s repositoriesReturns list of user’s repos for quick selection.

Page Routes (/app)

page.tsx

Homepage / Landing PageContains:
  • Hero section
  • Repository input form
  • Year selector
  • Feature highlights
Located at: /

layout.tsx

Root LayoutProvides:
  • HTML structure
  • Theme provider
  • Auth provider
  • Global metadata
  • Font loading
Wraps all pages

wrapped/[owner]/[repo]/[year]/page.tsx

Repository Wrapped PageDynamic route for wrapped stories.Example: /wrapped/facebook/react/2024Fetches data and renders WrappedStory

wrapped/user/[username]/[year]/page.tsx

User Wrapped PagePersonal year-in-code wrapped.Example: /wrapped/user/octocat/2024Renders UserWrappedStory

Components (/components)

Feature Components

1

RepositoryInput.tsx

Main input component for repository search.Features:
  • URL/slug parsing (owner/repo or full GitHub URL)
  • Real-time validation
  • Autocomplete suggestions
  • Error handling
  • Loading states
2

WrappedStory.tsx

Main container for wrapped presentation.Features:
  • Slide navigation (keyboard + buttons)
  • Progress indicator
  • Share functionality
  • Slide transitions
Location: components/WrappedStory.tsx:7885
3

WrappedSlide.tsx

Individual slide components (8-12 slides).Slides:
  • Intro slide with repo info
  • Commit statistics
  • Top contributors
  • Language breakdown
  • Community growth
  • Monthly trends
  • Special achievements
  • Share slide
Location: components/WrappedSlide.tsx:47979
4

UserWrappedStory.tsx & UserWrappedSlide.tsx

User-specific wrapped components.Personal stats including:
  • Total commits/PRs/issues
  • Top languages
  • Coding streaks
  • Busiest day/hour
  • Top repositories

UI Components (/components/ui)

Reusable, styled Radix UI primitives:
components/ui/
├── accordion.tsx        # Collapsible sections
├── alert-dialog.tsx     # Modal dialogs
├── avatar.tsx           # User avatars
├── button.tsx           # Button variants
├── card.tsx             # Card containers
├── carousel.tsx         # Image carousels
├── chart.tsx            # Chart components
├── dialog.tsx           # Dialogs
├── dropdown-menu.tsx    # Dropdown menus
├── input.tsx            # Form inputs
├── popover.tsx          # Popovers
├── select.tsx           # Select dropdowns
├── tooltip.tsx          # Tooltips
└── ...                  # 30+ more components
All UI components follow the shadcn/ui pattern: copy-paste, fully customizable, built on Radix UI.

Layout Components

  • hero.tsx - Landing page hero section
  • theme-provider.tsx - Dark/light mode provider
  • theme-toggle.tsx - Theme switcher component

Library Code (/lib)

Business logic and service layer:

github.ts

GitHub API ServiceGitHubService class with methods:
  • Repository operations
  • Commit fetching
  • Contributor queries
  • Rate limit management
Lines: 537

analytics.ts

Analytics EngineAnalyticsEngine class:
  • Data transformation
  • Statistics calculation
  • Insight generation
  • Trend analysis
Lines: 823

cache.ts

Caching LayerFunctions:
  • getCachedWrapped()
  • setCachedWrapped()
  • getCachedValidation()
  • Dual Redis/in-memory support
Lines: 178

auth.ts

Authentication Configbetter-auth configuration:
  • GitHub OAuth setup
  • Session management
  • Database adapter

authClient.ts

Auth ClientClient-side auth hooks and utilities.

redis.ts

Redis ClientUpstash Redis initialization:
  • Connection setup
  • Environment checks
  • Type-safe client
Lines: 12

utils.ts

Utility FunctionsHelper functions:
  • cn() - className merger
  • Date formatters
  • String utilities

Types (/types)

Centralized TypeScript type definitions:
// types/index.ts

export interface WrappedData { ... }
export interface UserWrappedData { ... }
export interface RepositoryInfo { ... }
export interface Contributor { ... }
export interface CommitStats { ... }
export interface LanguageStats { ... }
export interface MonthlySnapshot { ... }
export interface CacheEntry { ... }
All types are exported from a single file for easy imports:
import type { WrappedData, CommitStats } from '@/types'

Configuration Files

Next.js configuration:
  • TypeScript support
  • Image optimization settings
  • API route configuration
  • Build output settings
Tailwind CSS configuration:
  • Custom colors and themes
  • Dark mode settings
  • Plugin configuration (animate)
  • Custom utilities
TypeScript compiler options:
  • Path aliases (@/ → root)
  • Strict type checking
  • JSX configuration
  • Module resolution
ESLint configuration:
  • Next.js recommended rules
  • TypeScript rules
  • Code style enforcement
shadcn/ui configuration:
  • Component path
  • Utility path
  • Tailwind config
  • TypeScript settings

File Naming Conventions

Components

PascalCase.tsxExamples:
  • RepositoryInput.tsx
  • WrappedStory.tsx
  • UserProfile.tsx

Utilities & Services

camelCase.tsExamples:
  • github.ts
  • analytics.ts
  • cache.ts
  • utils.ts

Routes

lowercase with foldersExamples:
  • app/page.tsx
  • app/api/wrapped/route.ts
  • app/wrapped/[owner]/[repo]/[year]/page.tsx

Configuration

Various conventionsExamples:
  • next.config.ts
  • tailwind.config.ts
  • tsconfig.json
  • .env.local

Import Aliases

The project uses path aliases for cleaner imports:
// tsconfig.json
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./*"]
    }
  }
}
Usage:
// Instead of:
import { GitHubService } from '../../lib/github'
import type { WrappedData } from '../../types'

// Use:
import { GitHubService } from '@/lib/github'
import type { WrappedData } from '@/types'

Key Files Reference

FilePurposeLines
lib/github.tsGitHub API integration537
lib/analytics.tsAnalytics processing823
components/WrappedSlide.tsxSlide components~48k
components/WrappedStory.tsxStory container~8k
components/RepositoryInput.tsxInput form~12k
lib/cache.tsCaching layer178
types/index.tsType definitions131
Line counts are approximate and based on the current codebase. They may change as the project evolves.

Static Assets (/public)

Static files served at the root:
  • Favicon and app icons
  • Open Graph images
  • Robots.txt
  • Manifest files
Accessed via /filename.ext (e.g., /favicon.ico)

Build docs developers (and LLMs) love