FlashList v2: A ground-up rewrite for React Native's New Architecture
FlashList v2 is a complete rewrite that removes the need for item size estimates, delivers faster load times and improved scrolling performance, and is now production-ready. It powers thousands of lists in the Shopify mobile app.
Why a rewrite was necessary
FlashList v1 had several fundamental limitations that the team wanted to eliminate:
- Dependency on estimates: Developers had to provide an
estimatedItemSizeor per-item estimates viaoverrideItemLayoutto optimize initial load time and scrolling performance. - Native dependencies: Native modules were used to fix layout issues caused by inaccurate size estimations, preventing visual gaps and overlaps during loading. These modules sometimes conflicted with layout animations.
- Precision issues: Scrolling to specific items or maintaining scroll position during updates wasn't always accurate.
- Horizontal lists: Item heights couldn't be changed after the initial mount.
Eliminating estimates
FlashList v2 is designed to handle complex lists with components of different view types and heights, and it doesn't require developers to estimate each item type or provide an overall estimate. The list computes the layout of every item using absolute positioning, tracking left and top values for all items. Any inaccuracy in these values can result in gaps and overlaps during paint.
In v1, this round trip made it difficult to paint a clean layout without native help. React Native's New Architecture changes this with synchronous layout measurements:
Once items are measured and identified for correction, an update inside a useLayoutEffect can be performed. A state update in this hook blocks paint, which ensures no visual glitches. The update is kept fast to avoid increasing load times.
This approach enables the following:
- Measure layouts synchronously and adjust before anything is visible to the user.
- Eliminate the need for any native code.
- Simplify the implementation and add more features.
The rendering algorithm
The implementation is built on three pillars:
- Progressive rendering: As items render, a layout map is built that tracks exact sizes and calculates positions. Only one or two items are mounted during the initial render to avoid overdrawing. Once sizes are known, more items are rendered, ensuring visible content is prioritized and load times stay fast without estimates.
- Predictions: For unmeasured items, an estimate is tracked and updated as items of the same type render. Progressive rendering ensures that not too many items are drawn when a new item type is about to appear.
- Corrections: When predictions are wrong, layouts are corrected before the next paint inside a
useLayoutEffect. This happens in a loop until everything is corrected and ready to be painted.
This approach eliminates the need for native layout corrections and estimates entirely. All native code has also been removed from FlashList, which means fewer platform-specific issues and easier maintenance.
Pixel-perfect scrolling precision
Scroll operations in v1 were imprecise because estimates could be wrong and async measurements didn't allow real-time correction. The v2 scrolling system achieves precision through progressive refinement.
When you call scrollToIndex, the algorithm:
- Calculates the target position using the layout map
- Computes layouts of neighbouring items that could affect the target position
- Continuously refines the target position as new items are measured
- Initiates the scroll
- Lands exactly on the target item
Horizontal lists and adaptive rendering
Horizontal lists in v2 are significantly enhanced. Items can be any size and are resizable, with the list's height adjusting automatically. When a horizontal list is embedded in a vertical FlashList, it informs its parent to wait for its layout to complete before rendering, preventing over- or under-drawing.
Unlike v1's fixed render window, v2 uses an adaptive algorithm that considers scroll velocity and direction to set the draw buffer, and can adapt based on actual device render times. Benchmarks show up to 50% less blank area while scrolling on the new architecture compared to v1.
Handling data changes and new features
FlashList v2 reuses items to minimize renders while also supporting layout animations. A dedicated guide for setting up layout animations with Reanimated is planned.
Web support is improved since native components are no longer depended upon, making most new features available on the web.
New capabilities include:
maintainVisibleContentPosition: enabled by default, this prop maintains scroll position when content changes, suited for chat interfaces or real-time feeds. The same technique prevents layout jumps when items resize while scrolling upward or after orientation changes.- Masonry as a prop: masonry layout is now a FlashList prop and supports
overrideItemLayout, enabling items with varying column spans for more complex layouts. maxItemsInRecyclePool: gives control over the maximum number of items in the recycle pool, useful in extreme situations withgetItemTypeand many distinct item types.- New helper hooks: support seamless layout updates and synchronization of item state, which was difficult under the old architecture. Children can also more easily access the parent list's
ref.
FlashList v2 is ready for production. The upgrade path from v1 is straightforward, and the complete list of changes and features is available in the project's v2-changes documentation.



