Skip to content

πŸš€ Implementation Plan: GitHub Network ExplorerΒ #1

Description

@lupita-hom

πŸš€ GitHub Network Explorer β€” Implementation Plan

Overview

A stateless web application that extends the GitHub Repository Network Graph, providing an interactive, data-rich visualization of the relationships between branches, commits, tags, and pull requests. All data is fetched on-demand from the GitHub API via a GitHub App, with no persistent database.

Stitch Design Reference: GitGraph - GitHub Network Graph Explorer
Design System: "GitGraph Obsidian" β€” dark mode, glassmorphism, Inter + JetBrains Mono


πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      CLIENT (React)                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Auth Flow β”‚  β”‚  DAG Rendererβ”‚  β”‚  Detail Panels    β”‚  β”‚
β”‚  β”‚ (OAuth)  β”‚  β”‚  (d3-dag)    β”‚  β”‚  (Branches/PRs)   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚       β”‚               β”‚                    β”‚             β”‚
β”‚       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
β”‚                       β”‚                                  β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”                         β”‚
β”‚              β”‚  API Client     β”‚                         β”‚
β”‚              β”‚  (GraphQL +     β”‚                         β”‚
β”‚              β”‚   REST hybrid)  β”‚                         β”‚
β”‚              β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚ HTTPS
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚   API GATEWAY     β”‚
              β”‚   (Express/Node)  β”‚
              β”‚                   β”‚
              β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
              β”‚  β”‚ GitHub App  β”‚  β”‚
              β”‚  β”‚ Auth Layer  β”‚  β”‚
              β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β”‚
              β”‚         β”‚         β”‚
              β”‚  β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”  β”‚
              β”‚  β”‚ Cache Layer β”‚  β”‚
              β”‚  β”‚ (In-memory  β”‚  β”‚
              β”‚  β”‚  + TTL)     β”‚  β”‚
              β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β”‚
              β”‚         β”‚         β”‚
              β”‚  β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”  β”‚
              β”‚  β”‚ GraphQL +   β”‚  β”‚
              β”‚  β”‚ REST Client β”‚  β”‚
              β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚  GitHub API v4    β”‚
              β”‚  (GraphQL) +      β”‚
              β”‚  GitHub API v3    β”‚
              β”‚  (REST fallback)  β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“‹ Screens (from Stitch Design)

Screen 1: Dashboard β€” Network Graph Explorer

  • Main DAG visualization (60% viewport) β€” interactive commit graph
  • Right sidebar (30%) β€” selected commit/node detail panel
  • Bottom stats bar β€” repo health metrics (commits, branches, PRs, releases)
  • Left nav β€” collapsed icon sidebar (Dashboard, Branches, Tags, PRs, Settings)
  • Top nav β€” repo selector, branch filter pills, time range, user avatar

Screen 2: Branches Management

  • Branch list table with status, ahead/behind, linked PRs
  • Search/filter bar, branch comparison panel
  • Create/delete/archive actions

Screen 3: Pull Requests Feed

  • PR cards in vertical feed with status badges, CI/CD indicators
  • Filter tabs (Open/Closed/All), search, sort
  • PR detail preview panel

πŸ” Authentication & Authorization

GitHub App Setup

  1. Create GitHub App with the following permissions:
    • Repository: contents: read, metadata: read, pull_requests: read, commit_statuses: read
    • Organization: members: read (optional, for org repos)
  2. OAuth flow for user authentication:
    • User clicks "Connect with GitHub" β†’ OAuth redirect
    • Exchange code for user access token
    • Store token in session (httpOnly cookie, no DB)
  3. Installation token for API access:
    • GitHub App installation provides higher rate limits (5,000 β†’ 15,000 req/hr)
    • Use installation token for data fetching, user token for user-specific operations

Auth Flow

User β†’ "Connect with GitHub" β†’ GitHub OAuth β†’ Callback with code
  β†’ Exchange code for token β†’ Set httpOnly session cookie
  β†’ Redirect to dashboard β†’ Fetch repos user has access to

πŸ“‘ Data Fetching Strategy

Primary: GitHub GraphQL API (v4)

GraphQL is the primary data source β€” it reduces roundtrips dramatically compared to REST.

Key Queries

1. Repository Overview + Refs (branches, tags)

query RepoOverview($owner: String!, $name: String!) {
  repository(owner: $owner, name: $name) {
    defaultBranchRef { name target { oid } }
    refs(refPrefix: "refs/heads/", first: 100, orderBy: {field: TAG_COMMIT_DATE, direction: DESC}) {
      nodes {
        name
        target { oid ... on Commit { committedDate author { name avatarUrl } message } }
      }
    }
    tags: refs(refPrefix: "refs/tags/", first: 50, orderBy: {field: TAG_COMMIT_DATE, direction: DESC}) {
      nodes {
        name
        target { oid ... on Tag { target { oid } tagger { date } message } }
      }
    }
    pullRequests(first: 50, states: [OPEN, MERGED], orderBy: {field: UPDATED_AT, direction: DESC}) {
      nodes {
        number title state author { login avatarUrl }
        headRefName baseRefName
        mergeCommit { oid }
        commits(last: 1) { nodes { commit { oid } } }
        reviews(first: 5) { nodes { state author { login } } }
        labels(first: 5) { nodes { name color } }
      }
    }
  }
}

2. Commit History (per branch, paginated)

query BranchHistory($owner: String!, $name: String!, $branch: String!, $cursor: String) {
  repository(owner: $owner, name: $name) {
    ref(qualifiedName: $branch) {
      target {
        ... on Commit {
          history(first: 100, after: $cursor) {
            pageInfo { hasNextPage endCursor }
            nodes {
              oid
              message
              committedDate
              author { name email avatarUrl user { login } }
              parents(first: 5) { nodes { oid } }
              additions
              deletions
              changedFilesIfAvailable
              associatedPullRequests(first: 1) { nodes { number title state } }
              status { state contexts { context state targetUrl } }
            }
          }
        }
      }
    }
  }
}

3. Commit Detail (on-demand, when user clicks a node)

query CommitDetail($owner: String!, $name: String!, $oid: GitObjectID!) {
  repository(owner: $owner, name: $name) {
    object(oid: $oid) {
      ... on Commit {
        oid message committedDate
        author { name email avatarUrl user { login } }
        parents(first: 5) { nodes { oid abbreviatedOid message } }
        additions deletions changedFilesIfAvailable
        associatedPullRequests(first: 3) { nodes { number title state url } }
        tree { entries { name type } }
      }
    }
  }
}

Fallback: REST API (v3)

Used only when GraphQL doesn't expose what we need:

  • Compare API (GET /repos/{owner}/{repo}/compare/{base}...{head}) β€” for ahead/behind counts between branches
  • Commit diff files (GET /repos/{owner}/{repo}/commits/{sha}) β€” for file-level diff stats (if GraphQL tree isn't sufficient)

πŸ—‚οΈ DAG Construction Algorithm

This is the core logic β€” transforming flat commit lists into a renderable graph.

Step 1: Fetch & Merge Commit Histories

For each visible branch:
  1. Fetch last N commits (paginated via GraphQL)
  2. Collect into a Map<SHA, CommitNode>
  3. Deduplicate (same commit may appear in multiple branches)

Step 2: Build the DAG

interface CommitNode {
  sha: string;
  message: string;
  author: { name: string; avatar: string };
  timestamp: Date;
  parents: string[];        // parent SHAs
  children: string[];       // computed
  branches: string[];       // which branches contain this commit
  tags: string[];           // associated tags
  prs: PRReference[];       // associated PRs
  isMerge: boolean;         // parents.length > 1
  lane: number;             // computed β€” which visual column
}

// Build adjacency:
commits.forEach(c => {
  c.parents.forEach(parentSha => {
    const parent = commitMap.get(parentSha);
    if (parent) parent.children.push(c.sha);
  });
  c.isMerge = c.parents.length > 1;
});

Step 3: Lane Assignment (visual layout)

1. Topological sort commits by timestamp (newest first)
2. Assign "lanes" (columns) to branches:
   - main/master β†’ lane 0 (leftmost)
   - develop β†’ lane 1
   - feature branches β†’ lanes 2+
3. When branches merge, collapse lanes
4. When branches fork, expand lanes

Step 4: Render with d3-dag

- Use d3-dag library for DAG layout computation
- Each CommitNode β†’ SVG circle (or diamond for merges)
- Each parent→child relationship → SVG path (curved Bézier)
- Color-code by branch assignment
- Add interactive layers: hover tooltips, click β†’ detail panel

πŸ’Ύ Caching Strategy (Stateless, No Database)

Server-Side Cache (In-Memory with TTL)

// Using node-cache or Map with TTL wrapper
const cache = new NodeCache({ stdTTL: 300, checkperiod: 60 }); // 5 min default

// Cache keys:
// `repo:${owner}/${repo}:overview` β†’ branches, tags, PRs summary
// `repo:${owner}/${repo}:branch:${name}:commits` β†’ commit history per branch
// `repo:${owner}/${repo}:commit:${sha}` β†’ individual commit detail

// Conditional requests (ETag/If-Modified-Since):
// GitHub returns 304 Not Modified β†’ doesn't count against rate limit

Client-Side Cache

// React Query / TanStack Query with stale-while-revalidate
const { data } = useQuery({
  queryKey: ['repo', owner, repo, 'commits', branch],
  queryFn: () => fetchBranchCommits(owner, repo, branch),
  staleTime: 2 * 60 * 1000,    // 2 min stale
  gcTime: 10 * 60 * 1000,       // 10 min garbage collect
  refetchOnWindowFocus: true,
});

Webhook-Based Invalidation (via GitHub App)

GitHub App webhooks β†’ API Gateway:
  - `push` event β†’ invalidate branch commit cache
  - `create`/`delete` event β†’ invalidate refs cache
  - `pull_request` event β†’ invalidate PR cache
  
Notify connected clients via Server-Sent Events (SSE):
  Client subscribes: GET /api/events?repo=owner/repo
  Server pushes: { type: "cache_invalidated", scope: "branch:main" }
  Client refetches affected queries

πŸ“¦ Tech Stack

Layer Technology Rationale
Frontend React 19 + Vite Fast builds, modern React features
State Management TanStack Query v5 Built-in caching, deduplication, stale-while-revalidate
Graph Rendering d3-dag + d3.js Purpose-built DAG layout + SVG rendering
UI Components Tailwind CSS + shadcn/ui Matches Obsidian dark theme, utility-first
Backend Express.js (Node 22) Lightweight, pairs well with GitHub SDKs
GitHub SDK @octokit/graphql + @octokit/rest Official GitHub client libraries
Cache node-cache (in-memory) No DB dependency, TTL-based eviction
Real-time Server-Sent Events (SSE) Simpler than WebSockets for one-way push
Auth GitHub App OAuth + JWT sessions Stateless sessions, no DB needed
Deployment Docker + Docker Compose Single container, easy self-hosting
CI/CD GitHub Actions Dogfooding β€” running CI on the platform we visualize

πŸ“ Rate Limit Budget

Operation API Calls Frequency Notes
Repo overview (branches, tags, PRs) 1 GraphQL Per repo load Single query, cached 5min
Branch commit history (100 commits) 1 GraphQL per branch On-demand Paginate if needed
Full graph (5 branches Γ— 100 commits) ~5 GraphQL Initial load Parallelized
Commit detail 1 GraphQL On click Cached per SHA
Branch comparison (ahead/behind) 1 REST per pair On-demand REST Compare API
Total initial load ~7 requests Per repo Well within 5,000/hr

With GitHub App installation tokens: 15,000 req/hr β€” supports ~2,000 full repo loads per hour.


πŸ—“οΈ Implementation Phases

Phase 1: Foundation (MVP)

  • Project scaffolding (Vite + React + Express + Docker Compose)
  • GitHub App creation and OAuth flow
  • Basic GraphQL data fetching (repo overview, commit history)
  • DAG construction algorithm
  • Basic graph rendering with d3-dag (commit nodes + edges)
  • Branch lane assignment logic
  • Repository selector (list user's repos)

Phase 2: Core Features

  • Interactive graph (zoom, pan, click-to-select)
  • Commit detail sidebar panel
  • Branch filtering (show/hide branches on graph)
  • Tag markers on graph
  • PR merge point annotations
  • Time range filtering
  • Bottom stats bar (commit count, branch count, etc.)

Phase 3: Views & Navigation

  • Branches management view (list, search, filter, ahead/behind)
  • Pull Requests feed view (list, status, CI, reviews)
  • Left sidebar navigation
  • Branch comparison panel

Phase 4: Real-Time & Polish

  • Webhook integration (push, create, delete, PR events)
  • SSE for live cache invalidation
  • Graph mini-map navigator
  • Hover tooltips with commit info
  • Keyboard shortcuts (navigate commits, switch views)
  • Responsive design (tablet support)
  • Loading skeletons + error states

Phase 5: Advanced Features

  • Commit search (by SHA, author, message)
  • Graph export (SVG/PNG)
  • Multiple repo comparison view
  • Custom graph themes
  • URL-based deep linking (share specific commit/branch view)
  • Performance optimization for large repos (virtual scrolling, lazy branch loading)

πŸ“ Project Structure

github-network-explorer/
β”œβ”€β”€ client/                    # React frontend
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”œβ”€β”€ graph/         # DAG renderer, nodes, edges, minimap
β”‚   β”‚   β”‚   β”œβ”€β”€ layout/        # TopNav, Sidebar, BottomStats
β”‚   β”‚   β”‚   β”œβ”€β”€ panels/        # CommitDetail, BranchComparison
β”‚   β”‚   β”‚   └── ui/            # shadcn components
β”‚   β”‚   β”œβ”€β”€ features/
β”‚   β”‚   β”‚   β”œβ”€β”€ dashboard/     # Main graph dashboard
β”‚   β”‚   β”‚   β”œβ”€β”€ branches/      # Branches management
β”‚   β”‚   β”‚   └── pullrequests/  # PR feed
β”‚   β”‚   β”œβ”€β”€ hooks/             # useCommitHistory, useBranches, etc.
β”‚   β”‚   β”œβ”€β”€ lib/               # API client, DAG algorithms
β”‚   β”‚   └── styles/            # Tailwind config, Obsidian theme
β”‚   └── vite.config.ts
β”œβ”€β”€ server/                    # Express API gateway
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ routes/            # /api/repos, /api/graph, /api/events
β”‚   β”‚   β”œβ”€β”€ services/          # GitHubService, CacheService
β”‚   β”‚   β”œβ”€β”€ middleware/        # auth, rateLimit, errorHandler
β”‚   β”‚   └── utils/             # graphql queries, helpers
β”‚   └── package.json
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ Dockerfile
└── README.md

🎨 Design Assets

  • Stitch Project: https://stitch.withgoogle.com/projects/17186966880677404423
  • Design System: GitGraph Obsidian (dark mode, glassmorphism)
  • Color Palette:
    • Background: #0d1117 (deep slate)
    • Primary: #58a6ff (electric blue)
    • Success/Merged: #3fb950 (green)
    • PR/Secondary: #bc8cff (purple)
    • Warning: #d29922 (orange)
    • Error: #f85149 (red)
    • Muted text: #8b949e (gray)
  • Typography: Inter (UI), JetBrains Mono (code/SHAs)
  • Key Patterns: Glassmorphism panels, tonal layering (no hard borders), gradient CTAs


πŸ–ΌοΈ Design Screenshots (from Stitch)

Full interactive designs: GitGraph Stitch Project

1. Repository Network Dashboard

Repository Network Dashboard

2. Dashboard Graph Explorer

Dashboard Graph Explorer

3. Branches Management

Branches Management

4. Pull Requests Feed

Pull Requests Feed

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationplanningPlanning & architecture

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions