Reference version

This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

LazyColumn

A Jetpack Compose LazyColumn component for displaying scrollable lists.

Android
Included in Expo Go
Recommended version:
~58.0.10

Expo UI LazyColumn matches the official Jetpack Compose LazyColumn API and displays a vertically scrolling list.

LazyColumn rendering a settings list of five Material 3 list itemsLazyColumn rendering a settings list of five Material 3 list items

Installation

Terminal
- npx expo install @expo/ui
- yarn expo install @expo/ui
- pnpm expo install @expo/ui
- bun expo install @expo/ui

If you are installing this in an existing React Native app, make sure to install expo in your project.

Usage

Basic lazy column

Each child of LazyColumn is one row. Use the verticalArrangement prop to space the rows and the contentPadding prop to add padding around the list content.

BasicLazyColumn.tsx
import { Host, LazyColumn, ListItem, Text, } from '@expo/ui/jetpack-compose'; export default function BasicLazyColumn() { return ( <Host style={{ height: 400 }}> <LazyColumn verticalArrangement={{ spacedBy: 8 }}> <ListItem> <ListItem.HeadlineContent> <Text>Wi-Fi</Text> </ListItem.HeadlineContent> <ListItem.SupportingContent> <Text>Connected to Home</Text> </ListItem.SupportingContent> </ListItem> <ListItem> <ListItem.HeadlineContent> <Text>Bluetooth</Text> </ListItem.HeadlineContent> <ListItem.SupportingContent> <Text>On</Text> </ListItem.SupportingContent> </ListItem> <ListItem> <ListItem.HeadlineContent> <Text>Notifications</Text> </ListItem.HeadlineContent> <ListItem.SupportingContent> <Text>Allowed for all apps</Text> </ListItem.SupportingContent> </ListItem> </LazyColumn> </Host> ); }

Large lists

Use LazyColumn.Items to render rows from an array. Pass the items as data, a unique key for each item with keyExtractor, and a children function that returns the row for an item. LazyColumn.Items renders only the rows near the visible area and reuses them while you scroll.

LargeLazyColumn.tsx
import { Host, LazyColumn, ListItem, Text, } from '@expo/ui/jetpack-compose'; type Contact = { id: string; name: string }; const contacts: Contact[] = Array.from( { length: 10000 }, (_, i) => ({ id: String(i), name: `Contact ${i + 1}`, }) ); function renderContact({ item }: { item: Contact }) { return ( <ListItem> <ListItem.HeadlineContent> <Text>{item.name}</Text> </ListItem.HeadlineContent> </ListItem> ); } export default function LargeLazyColumn() { return ( <Host style={{ height: 400 }}> <LazyColumn> <LazyColumn.Items data={contacts} keyExtractor={contact => contact.id}> {renderContact} </LazyColumn.Items> </LazyColumn> </Host> ); }

Follow these rules when you render rows:

  • Define the children function outside the component, or wrap it in useCallback. Otherwise, the rows near the visible area render again each time the component renders.
  • A reused row keeps the local state (useState) of the item it showed before. Reset the state when the item changes, or keep the state outside the row.
  • A row that is not ready yet shows an empty placeholder. Set estimatedItemSize close to the height of your rows, in density-independent pixels (dp).
  • Use overscanCount to prepare more rows above and below the visible rows.
  • To update the rows, pass a new data array. Do not change the array in place.
  • Set recycling={false} to render every row up front.

API

import { LazyColumn } from '@expo/ui/jetpack-compose';

Components

LazyItems

Android

Type: React.Element<LazyItemsProps<T>>

A block of recycled rows inside LazyColumn or LazyRow, mirroring the Compose items(count, key) builder. Only a small pool of rows around the visible range is mounted, so large data sets stay cheap. Rows that are not ready yet show a placeholder of estimatedItemSize, or of the size last measured for that item.

Mount it as a direct child of LazyColumn or LazyRow.

LazyItemsProps

children

Android
Type: (info: { index: number, item: T }) => ReactElement

Renders an item. Wrap it in useCallback, or every item re-renders on each parent render. Recycled views are reused for other items, so their local state (useState) carries over. Reset it when the item changes, or keep the state outside the view.

data

Android
Type: readonly T[]

Items to display. Replace the array when updating data.

estimatedItemSize

Android
Optional • Type: number • Default: 64

Placeholder size in dp along the scroll axis, until an item is measured. Must be positive. Ignored when recycling is false.

keyExtractor

Android
Type: (item: T, index: number) => string

Returns a stable, unique string key, also used as the lazy list item key.

overscanCount

Android
Optional • Type: number • Default: 10

Extra items to prepare on each side of the visible items. Must be a non-negative integer. Ignored when recycling is false.

recycling

Android
Optional • Type: boolean • Default: true

Renders only the items near the visible range and reuses them while scrolling. Set to false to render every item at once. Set it once; changing it remounts the items.

LazyColumn

Android

Type: React.Element<LazyColumnProps>

A lazy column component that efficiently displays a vertically scrolling list.

LazyColumnProps

children

Android
Optional • Type: ReactNode

The content to display inside the lazy column.

contentPadding

Android
Optional • Type: ContentPadding

Content padding in dp.

horizontalAlignment

Android
Optional • Literal type: string

The horizontal alignment of items.

Acceptable values are: 'center' | 'start' | 'end'

modifiers

Android
Optional • Type: ModifierConfig[]

Modifiers for the component.

verticalArrangement

Android
Optional • Literal type: union

The vertical arrangement of items. Can be a preset string or an object with spacedBy to specify spacing in dp.

Acceptable values are: 'center' | 'top' | 'spaceBetween' | 'spaceAround' | 'spaceEvenly' | 'bottom' | { spacedBy: number }

Types

ContentPadding

Android

Content padding values for LazyColumn.

PropertyTypeDescription
bottom(optional)number

Bottom padding in dp.

end(optional)number

End padding in dp.

start(optional)number

Start padding in dp.

top(optional)number

Top padding in dp.