Introduction
When we first released FlashList back in 2022, our goal was simple: provide a drop-in replacement for FlatList that performs well. No blank cells, no janky scrolling, just smooth 60 FPS lists out of the box.
It has become extremely popular in the React Native community and has surpassed 2 million monthly downloads. It powers all of Shopify’s apps and those of several other companies of all sizes.
As React Native evolved with its New Architecture, we saw an opportunity to make it even better. Today, we're excited to share the technical details behind FlashList v2—a complete rewrite that’s faster, more precise, and easier to use than ever before. It’s already powering thousands of lists in the Shopify mobile app, and we’re thrilled to announce that it is now ready for production use!
In this blog, we talk about how v2 achieves amazing load times, scrolling performance and precision without you having to deal with item estimates.
The Motivation
While FlashList v1 was great, it had some fundamental limitations:
-
Dependency on Estimates: Developers had to provide an
estimatedItemSize
or estimates for individual items usingoverrideItemLayout
. We needed these values to optimize initial load time and scrolling performance. We tried to make providing these as simple as possible but it was always something we didn’t want. - Native Dependencies: Native modules addressed layout issues caused by inaccurate size estimations. We implemented UI thread corrections in native code for both Android and iOS to prevent visual gaps and overlaps during loading. These modules sometimes conflicted with layout animations, necessitating a mechanism to disable them when required.
- Precision Issues: Scrolling to specific items or maintaining scroll position during updates wasn't always accurate. Item level estimates were helpful but it just wasn’t always possible to estimate accurately.
- Horizontal Lists: It was not possible to change the height of items after the initial mount.
Eliminating Estimates
One of the best things about FlashList v2 is that you don’t have to think about estimates at all. FlashList is designed to support complex lists with components of different view types and heights. Many lists don’t have the same type of items and FlashList can manage them without developers having to estimate each type of item or providing an overall estimate.

FlashList computes the layout of every item and uses absolute position. The left and top value is computed for every item and any inaccuracy can mean gaps and overlaps when paint happens. In v1, we relied on native components like AutoLayoutView
to fix layout glitches before paint.
React Native's New Architecture introduced synchronous layout measurements. In the old architecture, measuring a view required an async bridge call:

This round trip could take time, making it difficult to paint a clean layout without native help. The New Architecture changes this completely:

Once we measure and identify some items that need to be corrected, we can do an update inside a useLayoutEffect
. A state update inside this hook blocks paint which works perfectly for our use case. We ensure the update is super quick to avoid increasing load times.

This opened up possibilities we couldn't achieve before:
- Measure layouts synchronously and make adjustments before the user can see.
- Eliminate the need for any native code
- Simplify the implementation and add more features.
The Algorithm That Makes It Possible
Our implementation builds on top of the following three pillars:
- Progressive Rendering: As items render, we build a layout map that tracks exact sizes and calculates positions. During the initial render we ensure we mount only one or two items to avoid drawing too much. Once we have a better idea of size we render more items. This ensures what’s visible to the user is rendered first and we don’t draw too little or too much. This provides amazing load times without any estimates.
- Predictions: For unmeasured items, we use an estimate which we track and update as items of the same type render. We use our progressive rendering technique to make sure that we don’t draw too many times when a new type of item is about to render.
-
Corrections: When predictions are wrong, we correct layouts before the next paint (inside a
useLayoutEffect
). This happens in a loop till everything is corrected and ready to be painted. The list’s design ensures that this part of the code is super fast and doesn’t impact load times.
This approach doesn’t need extra layout on UI thread and doesn’t need any estimates. Every load is fast without any gaps or overlaps of items!
It also allowed us to get rid of all native code which means less platform-specific issues and easier maintenance.
Solving precision problems
In FlashList v1, scrolling to a specific item was often imprecise because:
- We relied on estimates that could be wrong
- Async measurements meant we couldn't correct in real-time
The v2 Solution
Our new scrolling system achieves pixel-perfect precision through progressive refinement: As we approach the target, we measure and refine the scroll position.
When you call scrollToIndex
, the algorithm:
- Calculates the target position using the layout map
- Computes layouts of neighbouring items which can impact the target positon
- Continuously refines the target position as new items are measured
- Initiates the scroll
- Lands exactly on the target item, every time

Improved Horizontal Lists
FlashList v2 significantly enhances horizontal lists. Unlike v1, items can now be of any size and are resizable, automatically adjusting the list's height. When embedded in a vertical FlashList, these horizontal lists seamlessly coordinate to improve mounting and load times.
A horizontal list inside another FlashList will inform its parent to wait for its layout to complete before rendering. This coordination ensures the parent has the correct dimensions, preventing over or under-drawing.
Improved algorithms
Rendering
Unlike v1's fixed render window, v2 uses an adaptive algorithm that considers:
- Scroll Velocity and direction : We use a draw buffer based on scroll velocity and directions. We might use more of it in one direction than the other and it’s decided by the algorithms.
- Device Performance : The algorithm can adapt based on actual render times
On our benchmarks, we see up to 50% reduced blank area while scrolling on the new architecture compared to v1.
Data change handling
FlashList v2 is also smarter about handling data changes. We ensure that items are reused in a way that we minimize renders and also allow layout animations.
Layout Animations were possible with v1 and they’re improved with v2. It does take some work to get them set up with Reanimated and we’ll publish a separate guide for those soon.
Better support for web
FlashList v2 works a lot better on the web compared to v1. Since we don’t rely on native components, most of the new features and improvements are also available on the web.
Big new features:
Advanced Scroll Position Maintenance
The new maintainVisibleContentPosition
prop (enabled by default) intelligently maintains scroll position when content changes. Perfect for chat interfaces or feeds with real-time updates.

We use the same technique to prevent layout jumps when items are resizing as you’re scrolling upwards . For example, you scroll down, change device orientation and then scroll up or you have a very long list and you’re scrolling up after calling scrollToIndex
. This is one of our most favorite v2 improvements.
Improved Masonry Support
Masonry is now a prop on FlashList and supports overrideItemLayout
which means items can have varying column spans enabling much more complex layouts.

Control over recycle pool
You can now control the max number of items that can be in the recycle pool using the maxItemsInRecyclePool
prop. This can help in extreme situations where you’re using getItemType
and have a lot of them.
New helper hooks
We’ve added multiple new hooks that enable seamless layout updates, syncing item state which was a pain point in the old arch. It’s also simpler for children to access the parent list’s ref
if required. Read more here.
Conclusion
When we set out to rewrite FlashList, our goal was to solve the fundamental challenges that had been limiting v1: the need for estimates, precision issues, and platform-specific complexity. React Native's New Architecture gave us the tools to do something we couldn't before—build a list component that just works,with almost no developer overhead.
FlashList v2 eliminates estimates entirely, delivers pixel-perfect scrolling, and performs significantly better than its predecessor on the new architecture. More importantly, it removes the cognitive load that came with tuning the list settings. You no longer need to think about item sizes, provide estimates, or debug layout issues. You can focus on building great user experiences while FlashList handles its complex optimizations under the hood.
This rewrite represents more than just performance improvements—it's a fundamental shift in how list components can work in React Native. By leveraging synchronous measurements and progressive rendering, we've created a foundation that will continue to evolve with the platform.
FlashList v2 is ready for production today. Whether you're building your first React Native app or maintaining lists in a complex application with millions of users, the upgrade path is straightforward and the benefits are immediate.
Ready to get started? Upgrade to v2 today and experience the difference. For a complete list of changes and new features, click here.
About the author
Talha Naqvi is a Senior Staff Developer at Shopify.
X: @naqvitalha