30% offEnding soon
FSD-012Frontend system design Premium

Design a Tree View and File Explorer

Design an accessible, lazy, virtualized file explorer with predictable keyboard navigation, selection, rename, subtree moves, and conflict recovery.

Intermediate 52 min read

Store the hierarchy as normalized nodes and parent-child indexes, then derive a flattened visible preorder from expanded folders. Keep focus, selection, editing, loading, and mutations separate so lazy responses, virtualization, and concurrent changes cannot silently rewrite the user's current context.

A file explorer is often introduced as recursive rendering. Recursion is the easy part. The hard part appears when a folder opens before its children arrive, focus moves through only visible rows, selection spans collapsed branches, a rename conflicts, or a virtualizer removes the active row.

Derive rows from hierarchy and expansion

Persist stable node and parent relationships. Render a flat visible list produced by preorder traversal: include a node, then include its children only when it is expanded and those children are available. Each row carries node ID, depth, sibling position, parent ID, and expansion capability.

The flattened list gives keyboard navigation, windowing, range selection, and scrolling one shared coordinate system. The normalized tree remains the source of truth. Row indexes are temporary positions in the current projection.

The public interview prompt

Design a reusable tree view and file explorer for a cloud workspace. Explain:

  • normalized nodes, child indexes, path data, stable IDs, and visible-row flattening;
  • lazy expansion, caching, pagination, retries, cancellation, and stale responses;
  • ARIA tree semantics, arrow keys, type-ahead, focus, selection, and multi-select;
  • inline rename, create, delete, move, drag alternatives, undo, and conflicts;
  • cycle prevention, permissions, symbolic links or shortcuts, and deleted parents;
  • large-tree virtualization, variable row detail, search, reveal, and scroll restoration;
  • subscriptions, offline limits, instrumentation, tests, and rollout.

Assume one workspace can contain a million nodes, but fewer than 200 visible rows are normally near the viewport. Folder children arrive in pages. Other users can rename, move, or delete nodes. These are interview assumptions, not product measurements. File content editing and operating-system file transfer are outside version one.

What the premium solution covers

The full solution defines the normalized hierarchy, deterministic flattening, child-load state machine, generation guards, focus and selection models, APG keyboard behavior, rename and move transactions, cycle and permission checks, virtualized hierarchy metadata, reveal-by-path, subscriptions, degraded states, observability, tests, and an interview answer rubric.

Original media follows a lazy folder through load and cache reuse, maps normalized records into visible rows, separates four interaction rails, and validates a subtree move. Two deterministic labs exercise keyboard navigation and a stale-response race.

Premium solution

Continue with the complete system design

Unlock the architecture, state machine, API contracts, original diagrams, positioning model, accessibility decisions, performance budgets, testing plan, rollout strategy, scoring rubric, and interview walkthrough.

  • Detailed, beginner-friendly explanation
  • Production failure modes and trade-offs
  • Mobile-friendly architecture diagrams
  • Senior and staff-level interview signals
Unlock Premium

Frequently asked questions

Should tree focus and file selection use the same state?
No. Focus identifies the node receiving keyboard commands. Selection identifies the files or folders an action will affect. They may move together in a simple single-select tree, but the data model and visual treatment should remain distinct.
How should a file explorer load children lazily?
Give each folder an explicit child status and generation. Expanding starts one generation-scoped request. Apply its result only if the folder still exists and the response matches the latest generation and query context. Cache accepted children separately from expansion state.
Can an ARIA tree be virtualized?
Yes, but the active node must stay mounted or the focus strategy must move safely before unmounting it. Supply accurate level, position, and set-size metadata when the DOM does not contain all siblings, and keep logical selection outside row components.
How do you prevent moving a folder into itself?
Reject destinations equal to the source or any source descendant on both client and server. The server validates current ancestry and parent revisions in one transaction because a concurrent move can change the descendant relationship.
What happens if rename conflicts with another user?
Submit a stable node ID, proposed name, operation ID, and base revision. Preserve the input while pending. On conflict, show the accepted remote name beside the user's draft and let them retry or discard instead of silently overwriting either value.
Should collapsing a folder cancel its child request?
Cancel transport work when practical, but correctness must not depend on cancellation. A generation guard decides whether a late response can commit. Accepted children may remain cached so reopening is instant while expansion stays false.