Frontend System Design: Build the GitHub Repository UI

“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
  • 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-label on 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.

Scroll to Top