Reference version

PagerView

A horizontally paged view compatible with react-native-pager-view.

Android
iOS
Bundled version:
~56.0.12

For the complete documentation index, see llms.txt. Use this file to discover all available pages.

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

Terminal
npx expo install @expo/ui

If 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 setPage on iOS. Without worklets, iOS setPage falls back to a non-animated jump. Android animates regardless.
  • Per-frame onPageScroll callbacks that stay on the UI thread. When your onPageScroll handler 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, and overScrollMode are not supported.
  • The usePagerView hook is not provided — use a ref instead.
  • On iOS, onPageScroll and onPageScrollStateChanged only fire on iOS 18+.

See Platform behavior for the full list.

Basic usage

PagerViewExample.tsx
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.

FeatureAndroidiOS
Minimum platform versionAny supported versioniOS 17+ for paging. On iOS 16, the view scrolls horizontally but pages don't snap
onPageScroll / onPageScrollStateChangediOS 18+ only. On iOS 17, they never fire and the component logs a development warning on mount
Animated setPageNative pager animationRoutes 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, and overScrollMode are not supported. Only horizontal paging is available, and the others fall back to the platform pager's defaults.
  • The usePagerView hook is not provided. Use a ref to PagerView to access setPage, setPageWithoutAnimation, and setScrollEnabled.
  • setScrollEnabled triggers 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 borderRadius style 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

PagerView

Android
iOS

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.

Props for the PagerView component. Compatible with react-native-pager-view.

PagerViewProps

children

Android
iOS
Optional • Type: ReactNode

Pages of the pager. Each child is treated as a separate page and stretched to fill the pager. Each child should have a stable key.

initialPage

Android
iOS
Optional • Type: number • Default: 0

Index 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().

layoutDirection

Android
Optional • Literal type: string • Default: 'ltr'

Layout direction for paging.

Acceptable values are: 'ltr' | 'rtl'

offscreenPageLimit

Android
Optional • Type: number

Number of pages kept off-screen on each side of the visible page.

onPageScroll

Android
iOS 18.0+
Optional • Type: (event: PagerViewOnPageScrollEvent) => void

Fires 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.

onPageScrollStateChanged

Android
iOS 18.0+
Optional • Type: (event: PageScrollStateChangedEvent) => void

Fires when the scroll state changes between idle, dragging, and settling.

onPageSelected

Android
iOS
Optional • Type: (event: PagerViewOnPageSelectedEvent) => void

Fires when a page is fully selected. The event's position is the index of the new page.

pageMargin

Android
Optional • Type: number

Pixels of padding between pages.

ref

Android
iOS
Optional • Type: Ref<PagerViewRef>

Ref handle exposing imperative setPage, setPageWithoutAnimation, and setScrollEnabled methods.

scrollEnabled

Android
iOS
Optional • Type: boolean • Default: true

Whether the user can swipe between pages.

Inherited Props

Types

PagerViewOnPageScrollEvent

Android
iOS

Type: NativeSyntheticEvent<PagerViewOnPageScrollEventData>

PagerViewOnPageScrollEventData

Android
iOS

Type: Readonly<{ offset: number, position: number }>

PagerViewOnPageSelectedEvent

Android
iOS

Type: NativeSyntheticEvent<PagerViewOnPageSelectedEventData>

PagerViewOnPageSelectedEventData

Android
iOS

Type: Readonly<{ position: number }>

PagerViewRef

Android
iOS

Ref handle for the PagerView component.

PropertyTypeDescription
setPage(selectedPage: number) => void

Animate the pager to the given page index. Out-of-range indices are silently ignored. On iOS the animation requires react-native-worklets; without it, setPage falls back to a non-animated jump.

setPageWithoutAnimation(selectedPage: number) => void

Jump to the given page index without an animation.

setScrollEnabled(scrollEnabled: boolean) => void

Imperatively enable or disable user scrolling.

Note: If the scrollEnabled prop is also provided, subsequent prop changes win and reset the value set imperatively. To use the imperative path exclusively, omit the prop.

PageScrollStateChangedEvent

Android
iOS

Type: NativeSyntheticEvent<PageScrollStateChangedEventData>

PageScrollStateChangedEventData

Android
iOS

Type: Readonly<{ pageScrollState: 'idle' | 'dragging' | 'settling' }>