Try Live
Add Docs
Rankings
Pricing
Docs
Install
Theme
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
React Native Reanimated Carousel
https://github.com/dohooo/react-native-reanimated-carousel
Admin
The best carousel component in the React Native community, offering smooth animations and
...
Tokens:
47,771
Snippets:
192
Trust Score:
9.5
Update:
5 months ago
Context
Skills
Chat
Benchmark
87.5
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# React Native Reanimated Carousel React Native Reanimated Carousel is a high-performance carousel component for React Native applications, built on top of React Native Reanimated 2+ and React Native Gesture Handler. It provides smooth, fluid animations and supports multiple platforms including iOS, Android, and Web. The library offers infinite scrolling, customizable layouts, and various animation modes out of the box. The component is designed with performance in mind, leveraging Reanimated's worklet architecture to run animations on the native thread. It supports loop playback, auto-play functionality, gesture-based navigation, and programmatic control through imperative handles. The library includes pre-built layout modes (parallax, stack) and allows developers to create fully custom animations using worklets. ## Core Component ### Carousel Component The main carousel component that renders scrollable items with configurable animation modes and gesture handling. It uses Reanimated shared values for smooth animations and provides full control over scrolling behavior. ```tsx import React, { useRef } from 'react'; import { View, Text, Dimensions } from 'react-native'; import { useSharedValue } from 'react-native-reanimated'; import Carousel, { ICarouselInstance } from 'react-native-reanimated-carousel'; const { width } = Dimensions.get('window'); const data = [ { id: 1, color: '#B0604D', title: 'Slide 1' }, { id: 2, color: '#899F9C', title: 'Slide 2' }, { id: 3, color: '#B3C680', title: 'Slide 3' }, { id: 4, color: '#5C6265', title: 'Slide 4' }, { id: 5, color: '#F5D399', title: 'Slide 5' }, ]; function MyCarousel() { const carouselRef = useRef<ICarouselInstance>(null); const scrollOffsetValue = useSharedValue<number>(0); const renderItem = ({ item, index }) => ( <View style={{ flex: 1, backgroundColor: item.color, justifyContent: 'center', alignItems: 'center', borderRadius: 8, }} > <Text style={{ fontSize: 24, color: 'white' }}>{item.title}</Text> </View> ); return ( <View style={{ flex: 1 }}> <Carousel ref={carouselRef} loop={true} width={width} height={250} data={data} defaultIndex={0} autoPlay={true} autoPlayInterval={3000} scrollAnimationDuration={500} pagingEnabled={true} snapEnabled={true} defaultScrollOffsetValue={scrollOffsetValue} onSnapToItem={(index) => console.log('Current index:', index)} onScrollStart={() => console.log('Scroll started')} onScrollEnd={(index) => console.log('Scroll ended at:', index)} onProgressChange={(offsetProgress, absoluteProgress) => { console.log('Progress:', offsetProgress, absoluteProgress); }} renderItem={renderItem} /> </View> ); } export default MyCarousel; ``` ## Layout Modes ### Parallax Mode Creates a parallax scrolling effect where items scale and translate with offset positioning to create depth perception during scrolling. ```tsx import React from 'react'; import { View, Dimensions } from 'react-native'; import { useSharedValue } from 'react-native-reanimated'; import Carousel from 'react-native-reanimated-carousel'; const { width } = Dimensions.get('window'); const colors = ['#B0604D', '#899F9C', '#B3C680', '#5C6265', '#F5D399', '#F1F1F1']; function ParallaxCarousel() { const progress = useSharedValue<number>(0); return ( <View style={{ flex: 1, justifyContent: 'center' }}> <Carousel loop={true} width={width} height={250} data={colors} mode="parallax" modeConfig={{ parallaxScrollingScale: 0.9, parallaxScrollingOffset: 50, parallaxAdjacentItemScale: 0.8, }} onProgressChange={progress} renderItem={({ item, index }) => ( <View style={{ flex: 1, backgroundColor: item, borderRadius: 16, justifyContent: 'center', alignItems: 'center', }} /> )} /> </View> ); } export default ParallaxCarousel; ``` ### Horizontal Stack Mode Displays items in a stacked card layout where cards appear to stack behind each other with customizable spacing, rotation, and opacity effects. ```tsx import React from 'react'; import { View, Dimensions } from 'react-native'; import Carousel from 'react-native-reanimated-carousel'; const { width } = Dimensions.get('window'); const data = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']; function StackCarousel() { return ( <View style={{ flex: 1, justifyContent: 'center' }}> <Carousel loop={true} width={width} height={300} data={data} mode="horizontal-stack" modeConfig={{ snapDirection: 'left', moveSize: width, stackInterval: 30, scaleInterval: 0.08, rotateZDeg: 135, opacityInterval: 0.1, showLength: 3, }} renderItem={({ item, index }) => ( <View style={{ flex: 1, backgroundColor: item, borderRadius: 20, elevation: 5, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.25, shadowRadius: 3.84, }} /> )} /> </View> ); } export default StackCarousel; ``` ### Vertical Stack Mode Similar to horizontal stack but items stack vertically with configurable Y-axis transformations. ```tsx import React from 'react'; import { View, Dimensions } from 'react-native'; import Carousel from 'react-native-reanimated-carousel'; const { width, height } = Dimensions.get('window'); const data = ['#E74C3C', '#3498DB', '#2ECC71', '#F39C12', '#9B59B6']; function VerticalStackCarousel() { return ( <View style={{ flex: 1 }}> <Carousel loop={true} width={width * 0.8} height={height * 0.5} data={data} vertical={true} mode="vertical-stack" modeConfig={{ snapDirection: 'left', moveSize: height * 0.5, stackInterval: 20, scaleInterval: 0.04, rotateZDeg: 30, opacityInterval: 0.1, showLength: 3, }} renderItem={({ item }) => ( <View style={{ flex: 1, backgroundColor: item, borderRadius: 12, margin: 10, }} /> )} /> </View> ); } export default VerticalStackCarousel; ``` ## Custom Animations ### Custom Animation Function Create fully customized animations using worklets with access to the animation value and item index. ```tsx import React from 'react'; import { View, Dimensions, Text } from 'react-native'; import Carousel from 'react-native-reanimated-carousel'; import { interpolate, Extrapolation } from 'react-native-reanimated'; const { width } = Dimensions.get('window'); const data = Array.from({ length: 6 }, (_, i) => ({ id: i, label: `Item ${i + 1}` })); function CustomAnimationCarousel() { const customAnimation = (value: number, index: number) => { 'worklet'; const itemSize = width * 0.8; const inputRange = [-1, 0, 1]; const translateX = interpolate( value, inputRange, [-itemSize, 0, itemSize], Extrapolation.CLAMP ); const scale = interpolate( value, inputRange, [0.8, 1, 0.8], Extrapolation.CLAMP ); const opacity = interpolate( value, inputRange, [0.5, 1, 0.5], Extrapolation.CLAMP ); const rotateY = interpolate( value, inputRange, [-45, 0, 45], Extrapolation.CLAMP ); return { transform: [ { translateX }, { scale }, { rotateY: `${rotateY}deg` }, { perspective: 1000 }, ], opacity, }; }; return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Carousel loop={true} width={width * 0.8} height={200} data={data} customAnimation={customAnimation} renderItem={({ item }) => ( <View style={{ flex: 1, backgroundColor: '#4A90E2', borderRadius: 16, justifyContent: 'center', alignItems: 'center', }} > <Text style={{ fontSize: 32, color: 'white', fontWeight: 'bold' }}> {item.label} </Text> </View> )} /> </View> ); } export default CustomAnimationCarousel; ``` ## Imperative Controls ### Carousel Controller Methods Programmatically control carousel navigation using ref methods including next, prev, scrollTo, and getCurrentIndex. ```tsx import React, { useRef } from 'react'; import { View, Button, Text, StyleSheet } from 'react-native'; import Carousel, { ICarouselInstance } from 'react-native-reanimated-carousel'; const data = ['Red', 'Green', 'Blue', 'Yellow', 'Purple', 'Orange']; function ControlledCarousel() { const carouselRef = useRef<ICarouselInstance>(null); const handleNext = () => { carouselRef.current?.next({ count: 1, animated: true }); }; const handlePrev = () => { carouselRef.current?.prev({ count: 1, animated: true }); }; const handleScrollToIndex = (index: number) => { carouselRef.current?.scrollTo({ index, animated: true, onFinished: () => console.log('Scroll completed to index:', index), }); }; const handleGetCurrentIndex = () => { const currentIndex = carouselRef.current?.getCurrentIndex(); console.log('Current index:', currentIndex); }; const handleSkipAhead = () => { carouselRef.current?.scrollTo({ count: 3, animated: true, }); }; return ( <View style={{ flex: 1 }}> <Carousel ref={carouselRef} loop={false} width={300} height={200} data={data} defaultIndex={0} renderItem={({ item, index }) => ( <View style={{ flex: 1, backgroundColor: item.toLowerCase(), justifyContent: 'center', alignItems: 'center', }} > <Text style={{ fontSize: 24, color: 'white' }}> {item} - {index} </Text> </View> )} /> <View style={styles.controls}> <Button title="Previous" onPress={handlePrev} /> <Button title="Next" onPress={handleNext} /> <Button title="Go to Index 2" onPress={() => handleScrollToIndex(2)} /> <Button title="Skip 3 Items" onPress={handleSkipAhead} /> <Button title="Get Current Index" onPress={handleGetCurrentIndex} /> </View> </View> ); } const styles = StyleSheet.create({ controls: { flexDirection: 'column', gap: 10, padding: 20, }, }); export default ControlledCarousel; ``` ## Pagination Components ### Basic Pagination Built-in pagination indicator that automatically syncs with carousel progress using shared values. ```tsx import React from 'react'; import { View, Dimensions } from 'react-native'; import { useSharedValue } from 'react-native-reanimated'; import Carousel, { Pagination } from 'react-native-reanimated-carousel'; const { width } = Dimensions.get('window'); const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DFE6E9']; function CarouselWithPagination() { const progress = useSharedValue<number>(0); return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Carousel loop={true} width={width * 0.9} height={250} data={colors} autoPlay={true} autoPlayInterval={2000} onProgressChange={progress} renderItem={({ item, index }) => ( <View style={{ flex: 1, backgroundColor: item, borderRadius: 12, justifyContent: 'center', alignItems: 'center', }} /> )} /> <Pagination.Basic progress={progress} data={colors} horizontal={true} size={10} dotStyle={{ width: 10, height: 10, backgroundColor: '#CCCCCC', borderRadius: 5, }} activeDotStyle={{ width: 10, height: 10, backgroundColor: '#333333', borderRadius: 5, overflow: 'hidden', }} containerStyle={{ gap: 8, marginTop: 20, }} /> </View> ); } export default CarouselWithPagination; ``` ### Custom Pagination with Click Handler Pagination with custom styling and click-to-navigate functionality. ```tsx import React, { useRef } from 'react'; import { View, Dimensions, Text } from 'react-native'; import { useSharedValue } from 'react-native-reanimated'; import Carousel, { Pagination, ICarouselInstance } from 'react-native-reanimated-carousel'; const { width } = Dimensions.get('window'); const data = ['Slide 1', 'Slide 2', 'Slide 3', 'Slide 4', 'Slide 5']; function InteractivePaginationCarousel() { const carouselRef = useRef<ICarouselInstance>(null); const progress = useSharedValue<number>(0); const handlePaginationPress = (index: number) => { carouselRef.current?.scrollTo({ index, animated: true, }); }; return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Carousel ref={carouselRef} loop={false} width={width * 0.85} height={200} data={data} onProgressChange={progress} renderItem={({ item, index }) => ( <View style={{ flex: 1, backgroundColor: '#3498DB', borderRadius: 16, justifyContent: 'center', alignItems: 'center', }} > <Text style={{ fontSize: 28, color: 'white', fontWeight: '600' }}> {item} </Text> </View> )} /> <Pagination.Basic progress={progress} data={data} horizontal={true} size={12} onPress={handlePaginationPress} dotStyle={{ width: 30, height: 8, backgroundColor: 'rgba(0,0,0,0.2)', borderRadius: 4, }} activeDotStyle={{ width: 30, height: 8, backgroundColor: '#3498DB', borderRadius: 4, overflow: 'hidden', }} containerStyle={{ gap: 10, marginTop: 20, }} carouselName="Main Carousel" /> </View> ); } export default InteractivePaginationCarousel; ``` ## Advanced Features ### Progress Change Tracking Monitor carousel scroll progress with both offset and absolute progress values for synchronized animations or UI updates. ```tsx import React, { useState } from 'react'; import { View, Text, StyleSheet, Dimensions } from 'react-native'; import { useSharedValue } from 'react-native-reanimated'; import Carousel from 'react-native-reanimated-carousel'; const { width } = Dimensions.get('window'); const data = Array.from({ length: 5 }, (_, i) => `Page ${i + 1}`); function ProgressTrackingCarousel() { const [offsetProgress, setOffsetProgress] = useState(0); const [absoluteProgress, setAbsoluteProgress] = useState(0); return ( <View style={{ flex: 1 }}> <View style={styles.progressInfo}> <Text style={styles.progressText}> Offset Progress: {offsetProgress.toFixed(2)} </Text> <Text style={styles.progressText}> Absolute Progress: {absoluteProgress.toFixed(2)} </Text> <Text style={styles.progressText}> Current Page: {Math.round(absoluteProgress) + 1} </Text> </View> <Carousel loop={true} width={width} height={250} data={data} onProgressChange={(offset, absolute) => { setOffsetProgress(offset); setAbsoluteProgress(absolute); }} renderItem={({ item, index }) => ( <View style={[ styles.item, { backgroundColor: `hsl(${(index * 60) % 360}, 70%, 60%)` }, ]} > <Text style={styles.itemText}>{item}</Text> </View> )} /> </View> ); } const styles = StyleSheet.create({ progressInfo: { padding: 20, backgroundColor: '#F8F9FA', borderBottomWidth: 1, borderBottomColor: '#DDD', }, progressText: { fontSize: 16, marginBottom: 5, color: '#333', }, item: { flex: 1, justifyContent: 'center', alignItems: 'center', borderRadius: 8, }, itemText: { fontSize: 32, fontWeight: 'bold', color: 'white', }, }); export default ProgressTrackingCarousel; ``` ### Auto-Play with Reverse Direction Configure automatic scrolling with customizable intervals and reverse playback direction. ```tsx import React, { useState } from 'react'; import { View, Button, Dimensions } from 'react-native'; import Carousel from 'react-native-reanimated-carousel'; const { width } = Dimensions.get('window'); const colors = ['#E74C3C', '#3498DB', '#2ECC71', '#F39C12', '#9B59B6']; function AutoPlayCarousel() { const [autoPlay, setAutoPlay] = useState(true); const [reverse, setReverse] = useState(false); return ( <View style={{ flex: 1, justifyContent: 'center' }}> <Carousel loop={true} width={width} height={200} data={colors} autoPlay={autoPlay} autoPlayReverse={reverse} autoPlayInterval={2000} scrollAnimationDuration={500} renderItem={({ item, index }) => ( <View style={{ flex: 1, backgroundColor: item, justifyContent: 'center', alignItems: 'center', }} /> )} /> <View style={{ flexDirection: 'row', justifyContent: 'center', gap: 10, marginTop: 20 }}> <Button title={autoPlay ? 'Pause' : 'Play'} onPress={() => setAutoPlay(!autoPlay)} /> <Button title={reverse ? 'Forward' : 'Reverse'} onPress={() => setReverse(!reverse)} /> </View> </View> ); } export default AutoPlayCarousel; ``` ### Vertical Carousel Create vertical scrolling carousels with all the same features as horizontal mode. ```tsx import React from 'react'; import { View, Text, Dimensions } from 'react-native'; import Carousel from 'react-native-reanimated-carousel'; const { width, height } = Dimensions.get('window'); const data = ['Top', 'Middle', 'Bottom', 'Another', 'Last One']; function VerticalCarousel() { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Carousel loop={true} vertical={true} width={width * 0.8} height={height * 0.4} data={data} autoPlay={true} autoPlayInterval={3000} pagingEnabled={true} renderItem={({ item, index }) => ( <View style={{ flex: 1, backgroundColor: `hsl(${index * 72}, 60%, 50%)`, borderRadius: 20, justifyContent: 'center', alignItems: 'center', margin: 10, }} > <Text style={{ fontSize: 28, color: 'white', fontWeight: 'bold' }}> {item} </Text> </View> )} /> </View> ); } export default VerticalCarousel; ``` ### Gesture Configuration Customize pan gesture behavior with the onConfigurePanGesture callback for advanced gesture handling. ```tsx import React from 'react'; import { View, Text, Dimensions } from 'react-native'; import Carousel from 'react-native-reanimated-carousel'; import { GestureDetector, Gesture } from 'react-native-gesture-handler'; const { width } = Dimensions.get('window'); const data = ['Card 1', 'Card 2', 'Card 3', 'Card 4']; function CustomGestureCarousel() { return ( <View style={{ flex: 1, justifyContent: 'center' }}> <Carousel loop={true} width={width} height={200} data={data} onConfigurePanGesture={(panGesture) => { 'worklet'; // Configure gesture with custom settings panGesture .activeOffsetX([-20, 20]) .failOffsetY([-10, 10]); }} renderItem={({ item, index }) => ( <View style={{ flex: 1, backgroundColor: '#2C3E50', borderRadius: 12, justifyContent: 'center', alignItems: 'center', }} > <Text style={{ fontSize: 24, color: 'white' }}>{item}</Text> </View> )} /> </View> ); } export default CustomGestureCarousel; ``` ### Window Size Optimization Optimize performance by limiting the number of items that respond to gestures using the windowSize prop. ```tsx import React from 'react'; import { View, Text, Dimensions, Image } from 'react-native'; import Carousel from 'react-native-reanimated-carousel'; const { width } = Dimensions.get('window'); // Large dataset simulation const data = Array.from({ length: 100 }, (_, i) => ({ id: i, title: `Item ${i + 1}`, })); function OptimizedCarousel() { return ( <View style={{ flex: 1 }}> <Carousel loop={false} width={width} height={250} data={data} windowSize={11} pagingEnabled={true} renderItem={({ item, index }) => ( <View style={{ flex: 1, backgroundColor: `hsl(${(index * 3.6) % 360}, 70%, 60%)`, borderRadius: 8, justifyContent: 'center', alignItems: 'center', }} > <Text style={{ fontSize: 32, color: 'white', fontWeight: 'bold' }}> {item.title} </Text> </View> )} /> <View style={{ padding: 20 }}> <Text style={{ fontSize: 14, color: '#666' }}> Performance optimized: Only 11 items respond to gestures at a time </Text> </View> </View> ); } export default OptimizedCarousel; ``` ## Summary React Native Reanimated Carousel is the premier solution for implementing carousels in React Native applications, offering unmatched performance and flexibility. Its primary use cases include image galleries, onboarding flows, product showcases, story viewers, and any UI requiring smooth horizontal or vertical scrolling with custom animations. The library excels in scenarios demanding infinite loops, auto-play functionality, or complex custom animations while maintaining 60fps performance across all platforms. Integration is straightforward through npm or yarn installation, requiring React Native Reanimated 4.0.0+ and React Native Gesture Handler 2.9.0+ as peer dependencies. The component follows React Native's composition patterns, accepting familiar props like data arrays and renderItem functions. Developers can start with simple configurations and progressively enhance with advanced features like custom worklet animations, imperative controls via refs, progress tracking with shared values, and gesture customization. The built-in pagination components integrate seamlessly, and the modular architecture allows mixing pre-built layouts with fully custom animations for maximum design freedom.