Back to React
React
easy
mid

Would you use an existing library or build your own virtual scroll logic, and why?

Default to a battle-tested library (react-window, @tanstack/react-virtual, virtua) — they handle the gnarly edge cases. Build your own only when you have unusual requirements the libraries can't meet, and understand the core algorithm either way.

5 min read·~10 min to think through

The honest senior answer: use a library by default, and know why. Building your own is a deliberate exception, not a flex.

Use a library — almost always

react-window, @tanstack/react-virtual, virtua, react-virtuoso. They've already solved:

  • Scroll position math and the spacer/translate technique.
  • Variable and dynamic row heights with measurement caches.
  • Overscan buffering to avoid blank flashes.
  • Scroll-to-index, sticky items, grids, horizontal scrolling.
  • Resize handling, RTL, momentum scrolling quirks on iOS.
  • Accessibility hooks.

These are the exact things that take weeks to get right and break in subtle ways. Reinventing them is rarely a good use of time.

Understand the core algorithm anyway

Interviewers want to know you could build it:

  1. A scroll container with a tall inner spacer sized to totalCount × rowHeight (so the scrollbar is correct).
  2. On scroll, compute the visible index range from scrollTop, viewportHeight, rowHeight.
  3. Render only [startIndex - overscan, endIndex + overscan], absolutely positioned (or transform: translateY) at their real offsets.
  4. Variable heights → maintain a measured-height cache and a prefix-sum/position index to map scroll offset → index.

Build your own when…

  • You have highly unusual layout (masonry, nested virtualization, a custom scroll model) the libraries don't support.
  • You need to shave the dependency in a perf- or bundle-critical context.
  • The library's abstraction fights your data model badly.

Even then, consider forking or wrapping a library before going from scratch.

How to frame it in an interview

"I'd reach for @tanstack/react-virtual — it's headless, handles dynamic heights, and is well-tested. I'd build my own only if we had a layout it couldn't express. Either way the algorithm is: spacer for scroll height, compute the visible window from scrollTop, render window + overscan, absolutely positioned." That shows judgment and depth.

Follow-up questions

  • Walk me through the core virtualization algorithm.
  • What makes dynamic row heights hard?
  • What accessibility issues does virtualization introduce?
  • When is the dependency cost of a virtualization library not worth it?

Common mistakes

  • Building from scratch to show off, then missing dynamic heights / iOS scroll quirks.
  • Using a library but not understanding the algorithm when asked.
  • Virtualizing short lists that don't need it.
  • Ignoring accessibility (find-in-page, screen readers) regressions.

Performance considerations

  • Virtualization caps DOM nodes regardless of dataset size, drastically cutting memory and layout cost. The tradeoffs: scroll-jank risk if measurement is expensive, and accessibility/SEO regressions. Libraries amortize the hard parts; rolling your own means owning all of it.

Edge cases

  • Dynamic, unknown-until-rendered row heights.
  • Scroll-to-index into unrendered rows.
  • Nested or 2D (grid) virtualization.
  • Variable content causing measurement thrash.

Real-world examples

  • @tanstack/react-virtual powering a 100k-row data grid.
  • react-window in a chat app's message list.

Senior engineer discussion

The senior signal is judgment plus depth: defaulting to a proven library because the edge cases (dynamic heights, iOS momentum, a11y) are where time goes, while still being able to derive the spacer + visible-window algorithm on the spot. 'Build your own' is positioned as a justified exception, not a default.

Related questions