“Design GitHub’s repo page” is a senior+ frontend system-design prompt. The page combines a file tree, code viewer with syntax highlighting, blame, search, navigation, and a host of additional surfaces (issues, PRs, settings). The interview tests how you decompose a large product into a clean architecture and handle the size of real codebases.
Clarify scope
- Just the code tab or also issues / PRs / actions?
- Single language or multi-language code rendering?
- Mobile parity?
- Anonymous access (public repos) and authenticated access?
- Search (in-repo) and code-intelligence (jump to definition)?
Page structure
- Top: repo header (owner, repo name, stars, watchers, fork count)
- Tab navigation (Code, Issues, Pull requests, Actions, Projects, Wiki, Insights, Settings)
- Main: file tree on left, content on right
- Left panel collapses on narrow viewports
The file tree
Real repos have tens of thousands of files. Render strategy:
- Server returns the top-level directory by default
- Click a folder: server returns its contents (lazy)
- “Go to file” feature opens a flat search of all paths
- Virtualize when a single folder has 1000+ entries
The “Go to file” command
- Cmd+T or T to open
- Fuzzy match across the full path tree
- Server provides the path list for the repo (or a paginated subset)
- Client does the fuzzy search
- Performance: 100K paths fuzzy-search in <50 ms with the right algorithm (FZF-style)
The code viewer
- Syntax highlighting (Linguist for language detection, tree-sitter for tokenization)
- Line numbers
- Click a line: anchor URL, share link with line number
- Hover a symbol: code intelligence popup (defs, refs, type)
- Wide files: horizontal scroll vs word-wrap toggle
- Very large files: virtualize lines
Code intelligence
- Jump to definition
- Find references
- Hover for type
- Backed by SCIP / LSIF index that GitHub builds for popular repos
- Less reliable for less-popular repos; degrade gracefully
Blame view
- Each line annotated with author, commit, date
- Click an annotation: open the commit
- Server-side computed; cached
- Toggle blame on/off via query param
Branch and tag selection
- Dropdown with all branches and tags
- Search within the dropdown for repos with many branches
- Navigate between branches preserves file path when possible
- URL reflects the branch (so links survive sharing)
Diff view
- Used for commits, PRs, file history
- Side-by-side or inline
- Syntax-highlighted in both columns
- Comments on lines (PR review)
- Performance: handle PRs with 100s of files; lazy-load each file expansion
State management
- URL is the source of truth for: repo, branch, file path, view (code/blame/diff)
- State outside URL: client-side preferences (wrap mode, theme)
- React Query for server data with cache
- Avoid global stores; the page is mostly stateless given URL
Performance considerations
- Code rendering: chunked syntax highlighting (priority on visible lines)
- Tree expansion: lazy server fetch per folder
- Bundle size: split syntax-highlight grammars (load language-specific)
- SSR for the initial code view (perceived fast load)
- Service worker for repeat visits
Search
- In-repo code search via the search bar
- Backed by a code-search index (Sourcegraph, Zoekt-style)
- Results: file path with surrounding lines, ranked
- Filters: language, path, exclude tests
- Different from the “go to file” command (which is path-only)
Mobile considerations
- File tree as a sliding panel
- Code viewer with horizontal scroll (do not word-wrap by default)
- Pinch-zoom for code (very useful on phones)
- Reduced UI density
Accessibility
- File tree is a
role="tree"with proper keyboard navigation - Code viewer’s line numbers as
aria-labelon each line - Skip-link to main content for keyboard / screen-reader users
- Focus management on tab navigation
Editing in the browser
- Click “Edit” → Monaco / CodeMirror loads
- Save creates a commit (or proposes a PR if user lacks write access)
- Codespaces integration: open the repo in a cloud IDE
What separates senior from staff
Senior candidates draw the page structure and discuss the file tree lazy-loading. Staff candidates address the code-intelligence pipeline, the search index, and the diff-view performance for large PRs. Principal candidates raise the public/private access controls, the SSR caching strategy, and the mobile UX tradeoffs.
Frequently Asked Questions
How do I render a 50K-line file?
Virtualize the line render; chunk syntax highlighting; warn user about performance. Some platforms refuse to render very large files in the browser.
Which language for syntax highlighting?
Tree-sitter is the modern default for accuracy. Hljs / Prism are simpler. GitHub uses tree-sitter via Linguist.
How does code intelligence scale to all of GitHub?
Indexing is selective — popular repos and recently-touched code. Cold repos have less. Indexing is built async after pushes.