Skip to main content
This guide will help you migrate your existing FlashList v1 implementation to v2. FlashList v2 brings significant improvements in performance, developer experience, and new features while removing some deprecated props.

Overview of Major Changes

New architecture is required - v2 only works on top of React Native’s new architecture.

No More Estimates

FlashList v2 automatically handles all sizing - no estimates required

Masonry as Prop

MasonryFlashList component is deprecated - use the masonry prop instead

Better Scroll Position

maintainVisibleContentPosition enabled by default for better handling

Modern API

Inverted prop deprecated - use maintainVisibleContentPosition instead

Migration Steps

Step 1: Update Package Version

npm install @shopify/flash-list@^2.0.0

Step 2: Remove Deprecated Props

The biggest change in v2 is that you no longer need to provide size estimates. FlashList v2 automatically handles all sizing.
Before
<FlashList
  data={data}
  renderItem={renderItem}
  estimatedItemSize={50}
  estimatedListSize={{ height: 400, width: 300 }}
  estimatedFirstItemOffset={0}
/>
After
<FlashList
  data={data}
  renderItem={renderItem}
/>
Simply remove these props - they are no longer used or recognized:
  • estimatedItemSize
  • estimatedListSize
  • estimatedFirstItemOffset
Remove these deprecated props from your FlashList components:
<FlashList
  data={data}
  renderItem={renderItem}
- inverted={true}
- onBlankArea={handleBlankArea}
- disableHorizontalListHeightMeasurement={true}
- disableAutoLayout={true}
/>
Deprecated props:
  • inverted - Use maintainVisibleContentPosition instead (see Step 4)
  • onBlankArea - No longer supported
  • disableHorizontalListHeightMeasurement - No longer needed
  • disableAutoLayout - There’s no auto layout in v2

Step 3: Update Changed Props

In v1, overrideItemLayout allowed both span changes and size estimates. In v2, it only supports span changes.
v1 - Both span and size
overrideItemLayout={(layout, item, index) => {
  layout.span = item.span;
  layout.size = 100; // No longer supported in v2
}}
v2 - Only span supported
overrideItemLayout={(layout, item) => {
  layout.span = item.span; // Only span is supported
}}
Remove any layout.size assignments from your overrideItemLayout implementation. Only layout.span is supported in v2.

Step 4: Replace Inverted Lists

If you were using the inverted prop (common in chat apps), replace it with maintainVisibleContentPosition and consider reversing your data array.
v1 - Inverted list for chat
<FlashList
  data={messages}
  renderItem={renderMessage}
  inverted={true}
  onEndReached={loadMoreMessages}
/>
v2 - Use maintainVisibleContentPosition
<FlashList
  data={messages} // Can reverse if needed
  renderItem={renderMessage}
  maintainVisibleContentPosition={{
    autoscrollToBottomThreshold: 0.2,
    startRenderingFromBottom: true,
  }}
  onStartReached={loadMoreMessages} // Note: onStartReached instead of onEndReached
/>
The maintainVisibleContentPosition feature is enabled by default in v2, but you can configure it for chat-like behavior with startRenderingFromBottom and autoscrollToBottomThreshold.
Key changes:
  • Replace inverted={true} with maintainVisibleContentPosition configuration
  • Use onStartReached instead of onEndReached if loading older content from the top
  • Consider using startRenderingFromBottom: true for chat interfaces

Step 5: Migrate MasonryFlashList

The MasonryFlashList component is deprecated. Use the masonry prop on FlashList instead.
v1 - MasonryFlashList component
import { MasonryFlashList } from "@shopify/flash-list";

<MasonryFlashList
  data={data}
  renderItem={renderItem}
  numColumns={3}
  estimatedItemSize={100}
/>
v2 - FlashList with masonry prop
import { FlashList } from "@shopify/flash-list";

<FlashList
  data={data}
  renderItem={renderItem}
  numColumns={3}
  masonry
/>
Breaking Change: getColumnFlex from MasonryFlashList is not supported in v2.
New feature: You can now use optimizeItemArrangement prop to reduce differences in column height by modifying item order:
<FlashList
  data={data}
  renderItem={renderItem}
  numColumns={3}
  masonry
  optimizeItemArrangement
/>

Step 6: Update Ref Types

The ref type for FlashList has changed from FlashList to FlashListRef.
v1
import { FlashList } from "@shopify/flash-list";

const listRef = useRef<FlashList<ItemType>>(null);

<FlashList
  ref={listRef}
  data={data}
  renderItem={renderItem}
/>
v2
import { FlashList, FlashListRef } from "@shopify/flash-list";

const listRef = useRef<FlashListRef<ItemType>>(null);

<FlashList
  ref={listRef}
  data={data}
  renderItem={renderItem}
/>
The FlashListRef type provides access to all list methods:
  • scrollToIndex()
  • scrollToItem()
  • scrollToOffset()
  • getVisibleIndices()
  • getLayout()
  • And more…

Step 7: Replace CellContainer with View

CellContainer is no longer exported in v2. Replace it with React Native’s View.
v1
import { CellContainer } from "@shopify/flash-list";

const CustomCellRenderer = (props) => {
  return <CellContainer {...props} />;
};
v2
import { View } from "react-native";

const CustomCellRenderer = (props) => {
  return <View {...props} />;
};
Apps forwarding custom CellRendererComponent might need this change.

Additional Considerations

Memoization is More Important

Memoizing props passed to FlashList is more important in v2.
v1 was more selective about updating items, but this was often perceived as a bug by developers. v2 allows developers to ensure that props are memoized and will stop re-renders of children wherever it is obvious.
const memoizedData = useMemo(() => data, [data]);
const memoizedRenderItem = useCallback(
  ({ item }) => <Item item={item} />,
  []
);

<FlashList
  data={memoizedData}
  renderItem={memoizedRenderItem}
/>
keyExtractor is important to prevent glitches due to item layout changes when going upwards. We highly recommend having a valid keyExtractor with v2.
<FlashList
  data={data}
  keyExtractor={(item) => item.id}
  renderItem={renderItem}
/>

Remove Explicit key Props in renderItem

Scan your renderItem hierarchy for explicit key prop definitions and remove them.
If you’re doing a .map() inside your items, use the useMappingHelper hook:
import { useMappingHelper } from "@shopify/flash-list";

const MyItem = ({ items }) => {
  const { getMappingKey } = useMappingHelper();

  return (
    <View>
      {items.map((item, index) => (
        <Text key={getMappingKey(item.id, index)}>{item.title}</Text>
      ))}
    </View>
  );
};

Check useState in renderItem

Check your renderItem hierarchy for components that make use of useState and verify whether that state would need to be reset if a different item is passed to that component.
Consider using the new hooks:
  • useLayoutState - For state changes that affect layout
  • useRecyclingState - For state that should reset when item changes
See What’s New in v2 for detailed examples.

Performance Testing

Do not test performance with JS dev mode on. Make sure you’re in release mode.
FlashList can appear slower while in dev mode due to a small render buffer.
# iOS
npx react-native run-ios --configuration Release

# Android
npx react-native run-android --variant=release

Nesting Lists

If you’re nesting horizontal FlashLists in vertical lists, we highly recommend the vertical list to be FlashList too. We have optimizations to wait for child layout to complete which can improve load times.
<FlashList
  data={sections}
  renderItem={({ item }) => (
    <FlashList
      data={item.items}
      horizontal
      renderItem={({ item }) => <HorizontalItem item={item} />}
    />
  )}
/>

Migration Checklist

  • Update to @shopify/flash-list@^2.0.0
  • Remove size estimation props (estimatedItemSize, estimatedListSize, estimatedFirstItemOffset)
  • Remove deprecated props (inverted, onBlankArea, disableHorizontalListHeightMeasurement, disableAutoLayout)
  • Update overrideItemLayout to only use span (remove size)
  • Replace inverted with maintainVisibleContentPosition
  • Replace MasonryFlashList with FlashList + masonry prop
  • Update ref types from FlashList to FlashListRef
  • Replace CellContainer with View (if using custom cell renderer)
  • Remove explicit key props in renderItem hierarchy
  • Add keyExtractor if not already present
  • Memoize props passed to FlashList
  • Review useState usage in items - consider new hooks
  • Test performance in release mode

Next Steps

What's New in v2

Explore all the new features and improvements

Usage Guide

Learn about FlashList props and methods

Build docs developers (and LLMs) love