For a React chat feed, keep older-message prepends anchored to a stable message ID, and follow new output only when the reader is already near the bottom. Treat opening at the latest message, staying pinned during new output, and jumping to the latest on request as separate behaviors. TanStack Virtual documents controls for all three; React Virtuoso provides a higher-level component API with inverse-scroll and follow-output options.
Why chat feeds need a different scroll contract
A conventional list usually grows downward from the top. A chat feed changes in both directions: new messages append at the end, while loading older history prepends items at the beginning. At the same time, message heights may change as text streams in or media loads. A useful implementation must preserve the reader’s visible place during prepends without pulling someone reading history down to new output.
As an Amazon Associate I earn from qualifying purchases.
TanStack Virtual’s chat guide describes this distinction directly: “Chat, AI streams, logs, and other reverse feeds have a different scrolling contract than a standard top-anchored list.” TanStack Virtual’s chat guide presents a documented pattern for that contract.
Build the TanStack Virtual scroll behavior
TanStack Virtual is headless: it handles virtualization behavior, while your application supplies the markup and styles. The scroll element must have a constrained height and be scrollable; the library’s introduction demonstrates a fixed-height element with overflow: auto. The virtualizer needs the message count, a way to read that scroll element, an item-size estimate, and a stable key for each item.
#1 Best Overall
The relevant chat configuration combines anchorTo: 'end', followOnAppend: true, and a deliberate scrollEndThreshold. Consult the Virtualizer API documentation for current API details. Choose the threshold for the feel of your interface and test it; any value shown in documentation is an example, not a universal recommendation.
Use persistent message IDs as item keys
Return each message’s persistent ID from getItemKey. Do not use array indices: when older messages are prepended, every existing message’s index changes. Stable keys let the virtualizer recognize the same visible item across that data change.
With end anchoring, TanStack Virtual documents capturing the visible item before data changes, locating that same keyed item afterward, and adjusting the scroll offset so it stays in the same visual position. Prepend history while preserving message IDs to use this behavior.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Separate opening, following, and jumping
- Open at the latest message: If the product should initially show the newest content, call
scrollToEnd()after mount. - Follow new output conditionally: With
followOnAppend: true, TanStack Virtual follows an append only when the viewport was already at the end, within the configured threshold, before the append. Someone who has scrolled up to read history is not pulled down just because a new message arrives. - Jump on request: When the reader is away from the end, offer a “Jump to latest” control that calls
scrollToEnd().
These are distinct moments in the reader’s journey; do not make an initial positioning choice stand in for follow behavior or a user-requested jump.
Rank #3
Handle variable-height messages and late changes
Virtualized lists need an estimate or measurement for item size. TanStack Virtual exposes dynamic measurement, and its API documents that end anchoring keeps an end-pinned viewport pinned when the last item grows. That matters for streaming text, where the final message can expand after its first render. It does not establish that every dynamic layout will be jump-free in every browser or application.
React Virtuoso also supports height estimates that are replaced by measured values. Its API documents combining follow-output behavior with the imperative autoscrollToBottom() method when an image loads. Treat these as available mechanisms, not guarantees: media dimensions, layout changes, and application behavior still need testing.
Rank #4
TanStack Virtual or React Virtuoso?
| Decision | TanStack Virtual | React Virtuoso |
|---|---|---|
| Rendering model | Headless utility; your application owns markup and styles. See TanStack Virtual’s introduction. | Higher-level React list component with a component API. |
| Reverse-feed and chat controls | anchorTo: 'end', followOnAppend, scrollEndThreshold, and scrollToEnd(). |
firstItemIndex supports inverse infinite scrolling; followOutput follows changes when already at the bottom by default. |
| Item sizing | Configure estimates and measurement; the API exposes dynamic measurement. | Supports fixed item height, default height, and per-item height estimates; measured values replace estimates. |
| Trade-off | More control over structure and behavior, with more integration work. | More behavior is exposed through component props, with less direct control over low-level structure. |
React Virtuoso’s Virtuoso API reference documents its inverse-scroll, follow-output, sizing, restoration, and image-load controls. Choose between the libraries based on layout needs, desired low-level control, message-height variation, inverse-loading behavior, and restoration requirements. The documentation does not establish an independent performance benchmark or a universal no-jump guarantee for either library, so measure performance in your own application rather than inferring it from feature descriptions.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesVerify the behavior in the transitions that cause problems
Test more than the initial render. In particular, check:
Best Value
- Appending messages while the reader is pinned at the bottom, and while the reader is scrolled up.
- Prepending older history when the viewport is near the top, confirming the same visible message stays in place.
- A final message growing during streaming, including after the reader has moved away from the end.
- Images loading after their message has rendered.
- Restored sessions and fast scrolling through variable-height items that begin with estimates.
The cited library documentation describes APIs and examples; it does not establish browser-native CSS scroll-anchoring interoperability. Avoid assuming that a CSS anchoring setting will solve these cases without testing it in the application and browsers you support.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




