React Native pager component for swipeable pages, built on Jetpack Compose Pager on Android and SwiftUI TabView on iOS
TypeScript
3,366
559 commits
updated Oct 12, 2026
PagerView lets users swipe left and right (or up and down) through pages of content. It is a native component: on Android it renders a Jetpack Compose pager, and on iOS a SwiftUI paged TabView. See it in action!
npm install react-native-pager-view
# or
yarn add react-native-pager-view
# or
bun add react-native-pager-view
The library is autolinked. On iOS, install the pods afterwards:
cd ios && pod install
We support the three latest React Native versions: 0.85, 0.86 and 0.87. Only the New Architecture is supported.
import { StyleSheet, View, Text } from 'react-native';
import PagerView from 'react-native-pager-view';
export function MyPager() {
return (
<PagerView style={styles.pagerView} initialPage={0}>
<View key="1">
<Text>First page</Text>
</View>
<View key="2">
<Text>Second page</Text>
</View>
</PagerView>
);
}
const styles = StyleSheet.create({
pagerView: {
flex: 1,
},
});
Each direct child of PagerView becomes one page and is stretched to fill the pager. Give every child a unique key.
To control the pager from code, keep a ref and call its methods:
const ref = useRef<PagerView>(null);
// ...
<PagerView ref={ref} style={{ flex: 1 }}>
{pages}
</PagerView>;
// later
ref.current?.setPage(2);
For more examples, see the example app: nested pagers, keyboard handling, tab views, pagination dots, carousels and more.
| Prop | Description | Platform |
|---|---|---|
initialPage: number | Index of the page that is selected on mount. | both |
scrollEnabled: boolean | Whether the user can swipe between pages. Defaults to true. | both |
orientation: 'horizontal' | 'vertical' | Scroll direction. Defaults to horizontal. Changing it after mount is not supported. | both |
layoutDirection: 'ltr' | 'rtl' | 'locale' | Layout direction. Use ltr or rtl to set it explicitly, or locale to follow I18nManager.isRTL. Defaults to locale. | both |
pageMargin: number | Blank space between pages. | both |
keyboardDismissMode: 'none' | 'on-drag' | Whether the keyboard is dismissed when the user drags the pager. Defaults to none. | both |
onPageScroll: (e: PagerViewOnPageScrollEvent) => void | Called while moving between pages, either from a swipe or from an animated setPage. e.nativeEvent contains position and offset. | both |
onPageSelected: (e: PagerViewOnPageSelectedEvent) => void | Called once the pager settles on a page, and once on mount for initialPage. e.nativeEvent.position is the selected index. | both |
onPageScrollStateChanged: (e: PageScrollStateChangedNativeEvent) => void | Called when the scroll state changes. e.nativeEvent.pageScrollState is idle, dragging or settling. | both |
overdrag: boolean | Allows bouncing past the first and last page. Defaults to false. | iOS |
offscreenPageLimit: number | Number of pages kept composed on each side of the visible page. When unset, the Compose pager default is used. | Android |
overScrollMode: 'auto' | 'always' | 'never' | Overscroll effect at the edges. never disables the effect. Defaults to auto. | Android |
PagerView also accepts all standard View props.
| Method | Description | Platform |
|---|---|---|
setPage(index: number) | Scrolls to the given page with an animation. An invalid index is ignored. | both |
setPageWithoutAnimation(index: number) | Jumps to the given page without an animation. An invalid index is ignored. | both |
setScrollEnabled(scrollEnabled: boolean) | Enables or disables swiping imperatively. Prefer the scrollEnabled prop; use this when a re-render would get in the way, for example during an animation. | both |
The package exports these TypeScript types: PagerViewProps, PagerViewOnPageScrollEvent, PagerViewOnPageSelectedEvent, PageScrollStateChangedNativeEvent, and their *EventData payloads.
usePagerView hookusePagerView bundles the state and handlers you usually wire up yourself: the ref, the active page, the scroll state, the scroll progress, and helpers to add or remove pages and to toggle scrolling, animation and overdrag. It also returns AnimatedPagerView, which is PagerView wrapped with Animated.createAnimatedComponent.
import { View, Text } from 'react-native';
import { usePagerView } from 'react-native-pager-view';
export function PagerHookExample() {
const { AnimatedPagerView, ref, ...rest } = usePagerView({ pagesAmount: 10 });
return (
<AnimatedPagerView
ref={ref}
style={{ flex: 1 }}
initialPage={0}
scrollEnabled={rest.scrollEnabled}
overdrag={rest.overdrag}
onPageScroll={rest.onPageScroll}
onPageSelected={rest.onPageSelected}
onPageScrollStateChanged={rest.onPageScrollStateChanged}
>
{rest.pages.map((page) => (
<View key={page}>
<Text>{`Page ${page}`}</Text>
</View>
))}
</AnimatedPagerView>
);
}
The returned object also includes activePage, progress, scrollState, setPage, addPage, removePage, toggleScroll, toggleAnimation and toggleOverdrag. See the full example.
onPageScroll handlerTo handle onPageScroll on the UI thread with Reanimated, build an event handler with useEvent and pass it to an animated PagerView:
import PagerView from 'react-native-pager-view';
import Animated, { useEvent, useHandler } from 'react-native-reanimated';
const AnimatedPagerView = Animated.createAnimatedComponent(PagerView);
function usePageScrollHandler(handlers, dependencies) {
const { context, doDependenciesDiffer } = useHandler(handlers, dependencies);
return useEvent(
(event) => {
'worklet';
const { onPageScroll } = handlers;
if (onPageScroll && event.eventName.endsWith('onPageScroll')) {
onPageScroll(event, context);
}
},
['onPageScroll'],
doDependenciesDiffer
);
}
function MyPager() {
const handler = usePageScrollHandler({
onPageScroll: (e) => {
'worklet';
console.log(e.offset, e.position);
},
});
return <AnimatedPagerView style={{ flex: 1 }} onPageScroll={handler} />;
}
See the full example.
| horizontal | vertical |
|---|---|
![]() | ![]() |
| horizontal | vertical |
|---|---|
![]() | ![]() |
ViewPager2 to Jetpack Compose. The JavaScript API did not change.UIPageViewController to SwiftUI. The JavaScript API did not change.See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
Overall
Maintained
Code review
Latest release
Releases this year
1,553 followers · starred May 2020
6,017 followers · starred Aug 2022
1,803 followers · starred Jan 2021
404 followers · starred Apr 2025
React Native pager component for swipeable pages, built on Jetpack Compose Pager on Android and SwiftUI TabView on iOS
TypeScript
3,366
559 commits
updated Oct 12, 2026
PagerView lets users swipe left and right (or up and down) through pages of content. It is a native component: on Android it renders a Jetpack Compose pager, and on iOS a SwiftUI paged TabView. See it in action!
npm install react-native-pager-view
# or
yarn add react-native-pager-view
# or
bun add react-native-pager-view
The library is autolinked. On iOS, install the pods afterwards:
cd ios && pod install
We support the three latest React Native versions: 0.85, 0.86 and 0.87. Only the New Architecture is supported.
import { StyleSheet, View, Text } from 'react-native';
import PagerView from 'react-native-pager-view';
export function MyPager() {
return (
<PagerView style={styles.pagerView} initialPage={0}>
<View key="1">
<Text>First page</Text>
</View>
<View key="2">
<Text>Second page</Text>
</View>
</PagerView>
);
}
const styles = StyleSheet.create({
pagerView: {
flex: 1,
},
});
Each direct child of PagerView becomes one page and is stretched to fill the pager. Give every child a unique key.
To control the pager from code, keep a ref and call its methods:
const ref = useRef<PagerView>(null);
// ...
<PagerView ref={ref} style={{ flex: 1 }}>
{pages}
</PagerView>;
// later
ref.current?.setPage(2);
For more examples, see the example app: nested pagers, keyboard handling, tab views, pagination dots, carousels and more.
| Prop | Description | Platform |
|---|---|---|
initialPage: number | Index of the page that is selected on mount. | both |
scrollEnabled: boolean | Whether the user can swipe between pages. Defaults to true. | both |
orientation: 'horizontal' | 'vertical' | Scroll direction. Defaults to horizontal. Changing it after mount is not supported. | both |
layoutDirection: 'ltr' | 'rtl' | 'locale' | Layout direction. Use ltr or rtl to set it explicitly, or locale to follow I18nManager.isRTL. Defaults to locale. | both |
pageMargin: number | Blank space between pages. | both |
keyboardDismissMode: 'none' | 'on-drag' | Whether the keyboard is dismissed when the user drags the pager. Defaults to none. | both |
onPageScroll: (e: PagerViewOnPageScrollEvent) => void | Called while moving between pages, either from a swipe or from an animated setPage. e.nativeEvent contains position and offset. | both |
onPageSelected: (e: PagerViewOnPageSelectedEvent) => void | Called once the pager settles on a page, and once on mount for initialPage. e.nativeEvent.position is the selected index. | both |
onPageScrollStateChanged: (e: PageScrollStateChangedNativeEvent) => void | Called when the scroll state changes. e.nativeEvent.pageScrollState is idle, dragging or settling. | both |
overdrag: boolean | Allows bouncing past the first and last page. Defaults to false. | iOS |
offscreenPageLimit: number | Number of pages kept composed on each side of the visible page. When unset, the Compose pager default is used. | Android |
overScrollMode: 'auto' | 'always' | 'never' | Overscroll effect at the edges. never disables the effect. Defaults to auto. | Android |
PagerView also accepts all standard View props.
| Method | Description | Platform |
|---|---|---|
setPage(index: number) | Scrolls to the given page with an animation. An invalid index is ignored. | both |
setPageWithoutAnimation(index: number) | Jumps to the given page without an animation. An invalid index is ignored. | both |
setScrollEnabled(scrollEnabled: boolean) | Enables or disables swiping imperatively. Prefer the scrollEnabled prop; use this when a re-render would get in the way, for example during an animation. | both |
The package exports these TypeScript types: PagerViewProps, PagerViewOnPageScrollEvent, PagerViewOnPageSelectedEvent, PageScrollStateChangedNativeEvent, and their *EventData payloads.
usePagerView hookusePagerView bundles the state and handlers you usually wire up yourself: the ref, the active page, the scroll state, the scroll progress, and helpers to add or remove pages and to toggle scrolling, animation and overdrag. It also returns AnimatedPagerView, which is PagerView wrapped with Animated.createAnimatedComponent.
import { View, Text } from 'react-native';
import { usePagerView } from 'react-native-pager-view';
export function PagerHookExample() {
const { AnimatedPagerView, ref, ...rest } = usePagerView({ pagesAmount: 10 });
return (
<AnimatedPagerView
ref={ref}
style={{ flex: 1 }}
initialPage={0}
scrollEnabled={rest.scrollEnabled}
overdrag={rest.overdrag}
onPageScroll={rest.onPageScroll}
onPageSelected={rest.onPageSelected}
onPageScrollStateChanged={rest.onPageScrollStateChanged}
>
{rest.pages.map((page) => (
<View key={page}>
<Text>{`Page ${page}`}</Text>
</View>
))}
</AnimatedPagerView>
);
}
The returned object also includes activePage, progress, scrollState, setPage, addPage, removePage, toggleScroll, toggleAnimation and toggleOverdrag. See the full example.
onPageScroll handlerTo handle onPageScroll on the UI thread with Reanimated, build an event handler with useEvent and pass it to an animated PagerView:
import PagerView from 'react-native-pager-view';
import Animated, { useEvent, useHandler } from 'react-native-reanimated';
const AnimatedPagerView = Animated.createAnimatedComponent(PagerView);
function usePageScrollHandler(handlers, dependencies) {
const { context, doDependenciesDiffer } = useHandler(handlers, dependencies);
return useEvent(
(event) => {
'worklet';
const { onPageScroll } = handlers;
if (onPageScroll && event.eventName.endsWith('onPageScroll')) {
onPageScroll(event, context);
}
},
['onPageScroll'],
doDependenciesDiffer
);
}
function MyPager() {
const handler = usePageScrollHandler({
onPageScroll: (e) => {
'worklet';
console.log(e.offset, e.position);
},
});
return <AnimatedPagerView style={{ flex: 1 }} onPageScroll={handler} />;
}
See the full example.
| horizontal | vertical |
|---|---|
![]() | ![]() |
| horizontal | vertical |
|---|---|
![]() | ![]() |
ViewPager2 to Jetpack Compose. The JavaScript API did not change.UIPageViewController to SwiftUI. The JavaScript API did not change.See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
Overall
Maintained
Code review
Latest release
Releases this year
1,553 followers · starred May 2020
6,017 followers · starred Aug 2022
1,803 followers · starred Jan 2021
404 followers · starred Apr 2025