Monorepo Structure
The project uses a monorepo managed with pnpm workspaces:Apps
apps/web - Main Application
apps/web - Main Application
The primary Next.js application that powers Better Hub. This is where most development happens.Key directories:
src/app/- Next.js App Router pages and API routessrc/components/- React componentssrc/lib/- Shared utilities, auth, database, GitHub APIprisma/- Database schema and migrations
- Next.js 16 (App Router)
- React 19
- TypeScript 5.7
- Tailwind CSS 4
packages/chrome-extension
packages/chrome-extension
Browser extension that adds “Open in Better Hub” buttons to GitHub pages. Built as a separate package to allow independent deployment.
packages/firefox-extension
packages/firefox-extension
Firefox-compatible version of the browser extension, with Firefox-specific manifest and APIs.
Tech Stack
Frontend
- Next.js 16 - React framework with App Router
- React 19 - UI library
- TypeScript - Type-safe JavaScript
- Tailwind CSS 4 - Utility-first CSS framework
- Radix UI - Headless UI components
- TanStack Query - Data fetching and caching
- Motion - Animation library
- Tiptap - Rich text editor for comments
Backend
- Better Auth - Authentication library with GitHub OAuth
- Prisma - Database ORM and migrations
- PostgreSQL - Primary database
- Upstash Redis - Caching layer
- Octokit - GitHub API client
AI & ML
- Vercel AI SDK - AI integration framework
- Anthropic Claude - AI model for Ghost assistant
- OpenRouter - AI model routing and management
- Mixedbread AI - Embeddings for semantic search
- E2B - Code execution sandboxes
Infrastructure
- Vercel - Hosting and deployment
- Sentry - Error tracking and monitoring
- Stripe - Payments and subscriptions
- Inngest - Background job processing
- AWS S3 - File storage
Development Tools
- oxlint - Fast JavaScript/TypeScript linter
- oxfmt - Code formatter
- Bun - Package manager and task runner
- Docker Compose - Local PostgreSQL setup
Application Architecture
Directory Structure
The main application (apps/web/src/) is organized as follows:
Key Components
Authentication (lib/auth.ts)
Authentication (lib/auth.ts)
Better Hub uses Better Auth for authentication:
- GitHub OAuth with customizable scopes
- Encrypted OAuth token storage
- Session caching in cookies (JWE)
- Activity tracking and rate limiting
- Stripe customer creation on signup
- Admin plugin for user management
- Minimal default scopes (
read:user,user:email,public_repo) - Users can opt into additional scopes via UI
- PAT (Personal Access Token) sign-in support
- Automatic GitHub user data caching
Database (Prisma)
Database (Prisma)
Prisma manages the database schema and migrations:Location:
apps/web/prisma/schema.prismaKey models:- User, Session, Account (Better Auth)
- Subscription, Customer (Stripe billing)
- Custom user fields (GitHub PAT, onboarding state)
GitHub Integration (lib/github.ts)
GitHub Integration (lib/github.ts)
The GitHub client (
lib/github.ts) provides a comprehensive API wrapper:- Repository management (list, get, search)
- Pull request operations (list, get, create, merge)
- Issue tracking (list, get, create, update)
- Code navigation (file tree, file content, search)
- CI/CD status (workflow runs, checks)
- Security (advisories, vulnerabilities)
- Uses GitHub’s GraphQL API where possible (more efficient)
- Caches responses in Redis (Upstash)
- Implements exponential backoff for retries
- Uses OAuth tokens from Better Auth
- Supports GitHub PAT for enhanced permissions
- Automatically refreshes tokens when needed
AI Integration (Ghost)
AI Integration (Ghost)
Ghost is Better Hub’s AI assistant, powered by multiple AI services:Core files:
app/api/ai/- AI API endpointslib/ai-auth.ts- AI-specific authenticationlib/chat-store.ts- Conversation state managementlib/embedding-store.ts- Vector storage for semantic search
- PR review and summaries
- Code navigation and explanation
- Issue triage and labeling
- Commit message generation
- Natural language code search
- Anthropic Claude (primary reasoning)
- OpenRouter (model routing)
- Mixedbread AI (embeddings)
- E2B (code execution)
⌘I (or Ctrl+I) to toggle GhostBilling (Stripe)
Billing (Stripe)
Stripe integration for subscriptions and metered usage:Location:
lib/billing/Features:- Subscription plans (base tier)
- Metered billing for AI usage
- Credit system for new users
- Automatic customer creation on signup
- Webhook handling for subscription events
- Uses
@better-auth/stripeplugin - Syncs user data with Stripe customers
- Stores subscription status in database
Background Jobs (Inngest)
Background Jobs (Inngest)
Inngest handles asynchronous tasks:Location:
lib/inngest.ts, app/api/inngest/Use cases:- Repository data syncing
- Embedding generation for search
- Scheduled cleanup tasks
- Webhook processing
- Automatic retries with exponential backoff
- Event-driven architecture
- Built-in observability
Caching Strategy
Caching Strategy
Better Hub uses multiple caching layers:1. Redis (Upstash)
- GitHub API responses
- User session data
- Repository metadata
- README content
- Client-side data fetching
- Automatic background refetching
- Optimistic updates
- Static page generation
- Incremental Static Regeneration (ISR)
- Route caching
- Session cookie caching (7 days)
- Account data caching
Data Flow
Typical request flow for viewing a pull request:Authentication check
Next.js middleware validates session via Better Auth. If invalid, redirects to login.
Server component renders
Page component (
app/(app)/[owner]/[repo]/pull/[number]/page.tsx) fetches initial data server-side.GitHub API request
lib/github.ts client fetches PR data using cached OAuth token. Checks Redis cache first.Development Patterns
Server vs Client Components
Better Hub uses Next.js App Router with a clear separation: Server Components (default):- Page layouts and initial data fetching
- Authentication checks
- Database queries
- GitHub API calls
'use client'):
- Interactive UI (buttons, forms, modals)
- State management (React hooks)
- Real-time updates (TanStack Query)
- Keyboard shortcuts
API Routes
API routes (app/api/) handle:
- GitHub proxy endpoints (avoid CORS)
- AI streaming responses
- Webhook receivers (Stripe, GitHub)
- File uploads (S3/R2)
Type Safety
Strict TypeScript throughout:- No
anytypes in production code - Prisma generates database types
- Zod for runtime validation
- GitHub API types from Octokit
Performance Considerations
- Code splitting: Next.js automatically splits routes
- Image optimization: Next.js Image component for GitHub avatars
- Lazy loading: Dynamic imports for heavy components
- React Compiler: Automatic memoization (Babel plugin)
- Streaming: Server-side streaming for AI responses
Next Steps
Now that you understand the architecture:- Review the Setup Guide to get started
- Read the Contributing Guidelines for workflow details
- Explore the codebase with this knowledge in mind
- Ask questions in GitHub Discussions if anything is unclear