This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 57).
PagerView
A horizontally paged view compatible with react-native-pager-view.
A PagerView component with an API compatible with react-native-pager-view. It wraps the platform-specific @expo/ui primitives: Jetpack Compose HorizontalPager on Android and a paged SwiftUI ScrollView on iOS. Each child becomes a separate page and stretches to fill the pager.
If you need lower-level control over platform-specific paging behavior or modifiers, use the native primitives directly. On iOS, TabView with the page style also renders a horizontal pager and may fit better when you want SwiftUI's built-in page indicators.
Installation
- npx expo install @expo/uiIf you are installing this in an existing React Native app, make sure to install expo in your project.
Optionally, install react-native-worklets if you need either of the following:
- Animated
setPageon iOS. Without worklets, iOSsetPagefalls back to a non-animated jump. Android animates regardless. - Per-frame
onPageScrollcallbacks that stay on the UI thread. When youronPageScrollhandler is itself a worklet, it runs synchronously on the UI thread every frame instead of hopping to JS. Without worklets the callback still fires — it just runs on the JS thread.
Migrating from react-native-pager-view
Update the import statement by importing PagerView from @expo/ui/community/pager-view:
import PagerView from 'react-native-pager-view'; // becomes: import PagerView from '@expo/ui/community/pager-view';
Before you swap, you should know what changes:
orientation="vertical",keyboardDismissMode,overdrag, andoverScrollModeare not supported.- The
usePagerViewhook is not provided — use arefinstead. - On iOS,
onPageScrollandonPageScrollStateChangedonly fire on iOS 18+.
See Platform behavior for the full list.
Basic usage
import { useRef } from 'react'; import { Button, StyleSheet, Text, View } from 'react-native'; import PagerView, { type PagerViewRef } from '@expo/ui/community/pager-view'; export default function PagerViewExample() { const pagerRef = useRef<PagerViewRef>(null); return ( <View style={{ flex: 1 }}> <PagerView ref={pagerRef} style={{ flex: 1 }} initialPage={0} onPageSelected={event => { console.log('selected page', event.nativeEvent.position); }}> <View key="one" style={[styles.page, { backgroundColor: '#fde68a' }]}> <Text>Page one</Text> </View> <View key="two" style={[styles.page, { backgroundColor: '#bfdbfe' }]}> <Text>Page two</Text> </View> <View key="three" style={[styles.page, { backgroundColor: '#bbf7d0' }]}> <Text>Page three</Text> </View> </PagerView> <Button title="Go to page 2" onPress={() => pagerRef.current?.setPage(1)} /> </View> ); } const styles = StyleSheet.create({ page: { flex: 1, alignItems: 'center', justifyContent: 'center' }, });
Platform behavior
Web is not supported and rendering PagerView on web throws at runtime.
| Feature | Android | iOS |
|---|---|---|
| Minimum platform version | Any supported version | iOS 17+ for paging. On iOS 16, the view scrolls horizontally but pages don't snap |
onPageScroll / onPageScrollStateChanged | iOS 18+ only. On iOS 17, they never fire and the component logs a development warning on mount | |
Animated setPage | Native pager animation | Routes through react-native-worklets. Falls back to a non-animated jump if the package is not installed |
layoutDirection | ||
offscreenPageLimit | ||
pageMargin |
Additional differences from upstream react-native-pager-view:
orientation="vertical",keyboardDismissMode,overdrag, andoverScrollModeare not supported. Only horizontal paging is available, and the others fall back to the platform pager's defaults.- The
usePagerViewhook is not provided. Use areftoPagerViewto accesssetPage,setPageWithoutAnimation, andsetScrollEnabled. setScrollEnabledtriggers a re-render so the new value flows through to the native view as a prop. It is still useful for toggling from non-React contexts such as a ref-based gesture handler.- The
borderRadiusstyle applies on both platforms. On Android, only numeric values clip the pager. The underlying Compose host silently drops string values such as'50%'.
API
import PagerView from '@expo/ui/community/pager-view';
Component
Type: React.Element<PagerViewProps>
A drop-in replacement for react-native-pager-view. Renders a horizontally
paged view backed by Jetpack Compose's HorizontalPager on Android and
SwiftUI on iOS. Each child is treated as a separate page.
ReactNodePages of the pager. Each child is treated as a separate page and
stretched to fill the pager. Each child should have a stable key.
number • Default: 0Index of the page that is initially selected. Read once on mount;
later changes are ignored. To navigate after mount, call
ref.setPage() or ref.setPageWithoutAnimation().
string • Default: 'ltr'Layout direction for paging.
Acceptable values are: 'ltr' | 'rtl'
numberNumber of pages kept off-screen on each side of the visible page.
(event: PagerViewOnPageScrollEvent) => voidFires continuously while a swipe is in progress. The event's position
is the index of the leading visible page; offset is the fractional
progress toward the next page in the [0, 1) range.
Mark this handler with 'worklet' (requires react-native-worklets)
to run it synchronously on the UI thread every frame.
(event: PageScrollStateChangedEvent) => voidFires when the scroll state changes between idle, dragging,
and settling.
(event: PagerViewOnPageSelectedEvent) => voidFires when a page is fully selected. The event's position is the
index of the new page.
Ref<PagerViewRef>Ref handle exposing imperative setPage, setPageWithoutAnimation,
and setScrollEnabled methods.
boolean • Default: trueWhether the user can swipe between pages.
Types
Type: NativeSyntheticEvent<PagerViewOnPageScrollEventData>
Type: Readonly<{
offset: number,
position: number
}>
Type: NativeSyntheticEvent<PagerViewOnPageSelectedEventData>
Type: Readonly<{
position: number
}>
Ref handle for the PagerView component.
| Property | Type | Description |
|---|---|---|
| setPage | (selectedPage: number) => void | Animate the pager to the given page index. Out-of-range indices are
silently ignored. On iOS the animation requires |
| setPageWithoutAnimation | (selectedPage: number) => void | Jump to the given page index without an animation. |
| setScrollEnabled | (scrollEnabled: boolean) => void | Imperatively enable or disable user scrolling.
|
Type: NativeSyntheticEvent<PageScrollStateChangedEventData>
Type: Readonly<{
pageScrollState: 'idle' | 'dragging' | 'settling'
}>