tinder like react-native deck swiper





GitHub Stars



Last Commit

1yr ago








Type Definitions






contributions welcome npm version


yarn add react-native-deck-swiper


npm install react-native-deck-swiper --save

Versions info

Version 2.0.0-beta is technically version 1.7.2 of the package. However, npm recommended that due to the change in ownership the version be bumped.

<= 2.0.3-beta<= 0.56.xshould install react-native-view-overflow and set useViewOverflow true
>= 2.0.4=> 0.57.xno longer requires react-native-view-overflow; useViewOverflow removed


Before submitting a new issue please check if it hasn't already been reported yet. With respect to bugfixes and further developments, please check the To Do board.


  • Rotation animation
  • Opacity animation
  • Zoom animation
  • Overlay labels
  • Show next card while swiping
  • Swipe event callbacks
  • Trigger swipe animations programmatically
  • Jump to a card index
  • Swipe to previous card
  • Underlaying cards offset
  • Never-ending, animated deck when infinite property is true
  • Swipe back to previous card with a custom animation


App preview App preview2


Card props

cardsarrayarray of data for the cards to be renderedrequired
renderCardfunc(cardData, cardIndex)function to render the card based on the datarequired
keyExtractorfunc(cardData)function to get the card's react keynull
cardIndexnumbercardIndex to start with0
infiniteboolkeep swiping indefinitelyfalse
horizontalSwipeboolenable/disable horizontal swipingtrue
verticalSwipeboolenable/disable vertical swipingtrue
showSecondCardboolenable/disable second card while swipingtrue
stackSizenumbernumber of underlaying cards to show (showSecondCard must be enabled)1

Event callbacks

onSwipedAllfuncfunction to be called when all cards have been swiped
onSwipedfuncfunction to be called when a card is swiped. it receives the swiped card index
onSwipedAbortedfuncfunction to be called when a card is released before reaching the threshold
onSwipedLeftfuncfunction to be called when a card is swiped left. it receives the swiped card index
onSwipedRightfuncfunction to be called when a card is swiped right. it receives the swiped card index
onSwipedTopfuncfunction to be called when a card is swiped top. it receives the swiped card index
onSwipedBottomfuncfunction to be called when a card is swiped bottom. it receives the swiped card index
onSwipingfuncfunction to be called when a card is being moved. it receives X and Y positions
dragStartfuncfunction to be called when drag start
dragEndfuncfunction to be called when drag end
onTapCardfuncfunction to be called when tapping a card. it receives the tapped card index
onTapCardDeadZonenumbermaximum amount of movement before a tap is no longer recognized as a tap5

Swipe animation props

verticalThresholdnumbervertical swipe thresholdheight / 5
horizontalThresholdnumberhorizontal swipe thresholdwidth / 4
swipeAnimationDurationnumberduration of the swipe animation350
disableBottomSwipebooldisable bottom swipefalse
disableLeftSwipebooldisable left swipefalse
disableRightSwipebooldisable right swipefalse
disableTopSwipebooldisable top swipefalse

Stack props

stackSeparationnumbervertical separation between underlaying cards10
stackScalenumberpercentage to reduce the size of each underlaying card3
stackAnimationFrictionnumberspring animation friction (bounciness)7
stackAnimationTensionnumberspring animation tension (speed)40

Rotation animation props

inputRotationRangearrayx values range for the rotation output[-width / 2, 0, width / 2]
outputRotationRangearrayrotation values for the x values in inputRotationRange["-10deg", "0deg", "10deg"]

Opacity animation props

animateCardOpacityboolanimate card opacityfalse
inputCardOpacityRangeXarraypan x card opacity input range[-width / 2, -width / 3, 0, width / 3, width / 2]
outputCardOpacityRangeXarrayopacity values for the values in inputCardOpacityRangeX[0.8, 1, 1, 1, 0.8]
inputCardOpacityRangeYarraypan y card opacity input range[-height / 2, -height / 3, 0, height / 3, height / 2]
outputCardOpacityRangeYarrayopacity values for the values in inputCardOpacityRangeY[0.8, 1, 1, 1, 0.8]
animateOverlayLabelsOpacityboolanimate card overlay labels opacityfalse
inputOverlayLabelsOpacityRangeXarraypan x overlay labels opacity input range[-width / 3, -width / 4, 0, width / 4, width / 3]
outputOverlayLabelsOpacityRangeXarrayopacity values for the values in inputOverlayLabelsOpacityRangeX[1, 0, 0, 0, 1]
inputOverlayLabelsOpacityRangeYarraypan x overlay labels opacity input range[-height / 4, -height / 5, 0, height / 5, height / 4]
outputOverlayLabelsOpacityRangeYarrayopacity values for the values in inputOverlayLabelsOpacityRangeY[1, 0, 0, 0, 1]
overlayOpacityVerticalThresholdnumbervertical threshold for overlay labelheight / 5
overlayOpacityHorizontalThresholdnumberhorizontal threshold for overlay labelwidth / 4

2 steps of inputOverlayLabelsOpacityRangeX and inputOverlayLabelsOpacityRangeY should match horizontalThreshold and verticalThreshold, respectively.

Swipe overlay labels

overlayLabelsobjectswipe labels title and stylenull, see below for format
overlayLabelStyleobjectswipe labels stylenull, see below for format
overlayLabelWrapperStyleobjectoverlay label wrapper stylesee below for default


  fontSize: 45,
  fontWeight: 'bold',
  borderRadius: 10,
  padding: 10,
  overflow: 'hidden'

overlayLabelWrapperStyle default props:

  position: 'absolute',
  backgroundColor: 'transparent',
  zIndex: 2,
  flex: 1,
  width: '100%',
  height: '100%'

overlayLabels default props :

  bottom: {
    element: <Text>BLEAH</Text> /* Optional */
    title: 'BLEAH',
    style: {
      label: {
        backgroundColor: 'black',
        borderColor: 'black',
        color: 'white',
        borderWidth: 1
      wrapper: {
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center'
  left: {
    element: <Text>NOPE</Text> /* Optional */
    title: 'NOPE',
    style: {
      label: {
        backgroundColor: 'black',
        borderColor: 'black',
        color: 'white',
        borderWidth: 1
      wrapper: {
        flexDirection: 'column',
        alignItems: 'flex-end',
        justifyContent: 'flex-start',
        marginTop: 30,
        marginLeft: -30
  right: {
    element: <Text>LIKE</Text> /* Optional */
    title: 'LIKE',
    style: {
      label: {
        backgroundColor: 'black',
        borderColor: 'black',
        color: 'white',
        borderWidth: 1
      wrapper: {
        flexDirection: 'column',
        alignItems: 'flex-start',
        justifyContent: 'flex-start',
        marginTop: 30,
        marginLeft: 30
  top: {
    element: <Text>SUPER</Text> /* Optional */
    title: 'SUPER LIKE',
    style: {
      label: {
        backgroundColor: 'black',
        borderColor: 'black',
        color: 'white',
        borderWidth: 1
      wrapper: {
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center'

Swipe back to previous card props

Make sure you set showSecondCard={false} for smoother and proper transitions while going back to previous card.

goBackToPreviousCardOnSwipeLeftboolprevious card is rendered on left swipefalse
goBackToPreviousCardOnSwipeRightboolprevious card is rendered on right swipefalse
goBackToPreviousCardOnSwipeTopboolprevious card is rendered on top swipefalse
goBackToPreviousCardOnSwipeBottomboolprevious card is rendered on bottom swipefalse

Style props

backgroundColorstringbackground color for the view containing the cards'#4FD0E9'
marginTopnumbermarginTop for the swiper container0
marginBottomnumbermarginBottom for the swiper container0
cardVerticalMarginnumbercard vertical margin60
cardHorizontalMarginnumbercard horizontal margin20
childrenOnTopboolrender children on top or notfalse
cardStylenodeoverride swipable card style{}
containerStylenodeoverrides for the containing style{}
pointerEventsstringpointerEvents prop for the containing 'auto'
useViewOverflowbooluse ViewOverflow instead of View for the Swiper componenttrue

Swipe back method info


swipeBackcallbackswipe back into deck last swiped card. stacksize should be 2 cards or more


previousCardDefaultPositionXnumberAnimation start position oX when card swipes back into deck-width
previousCardDefaultPositionYnumberAnimation start position oY when card swipes back into deck-height
stackAnimationFrictionnumberspring animation friction (bounciness)7
stackAnimationTensionnumberspring animation tension (speed)40
stackAnimationTensionnumberspring animation tension (speed)40
swipeBackCardboolrenders swipe back card, in order to animate itfalse


To trigger imperative animations, you can use a reference to the Swiper component.

swipeLeftmustDecrementCardIndex = falseswipe left to the next card
swipeRightmustDecrementCardIndex = falseswipe right to the next card
swipeTopmustDecrementCardIndex = falseswipe top to the next card
swipeBottommustDecrementCardIndex = falseswipe bottom to the next card
jumpToCardIndexcardIndexset the current card index

Usage example

render () {
    <View style={styles.container}>
            cards={['DO', 'MORE', 'OF', 'WHAT', 'MAKES', 'YOU', 'HAPPY']}
            renderCard={(card) => {
                return (
                    <View style={styles.card}>
                        <Text style={styles.text}>{card}</Text>
            onSwiped={(cardIndex) => {console.log(cardIndex)}}
            onSwipedAll={() => {console.log('onSwipedAll')}}
            stackSize= {3}>
                onPress={() => {console.log('oulala')}}
                title="Press me">
                You can press me

Demo inside the Example Folder

Stylesheet example

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#F5FCFF"
  card: {
    flex: 1,
    borderRadius: 4,
    borderWidth: 2,
    borderColor: "#E8E8E8",
    justifyContent: "center",
    backgroundColor: "white"
  text: {
    textAlign: "center",
    fontSize: 50,
    backgroundColor: "transparent"

Updating props on card content? (dynamic card content)

Card properties may change, including on already swiped cards, which would yield no effects to users as the cards would no longer be displayed [based on initial issue].

A possible fix for the situation is setting the cardIndex on the parent component whenever deck re-renders are needed.

const { cardIndex } = this.props;
return (<Swiper
  ref={swiper => {
    this.swiper = swiper;

Passing along the cardIndex to the swiper will allow external changes on the property, thus triggering a re-render of the deck of cards. All onSwipe callbacks return the cardIndex that can be used to push the updated cardIndex to app state (redux or something else).

By making sure that external changes on the cardIndex match those the swiper performs (increment on swipes, decrement on swipeBack) one can ensure no re-renders occur when not needed.


If you've encountered issues while running the example app located in the example folder, try the following steps:

If you're using yarn

  1. rm -rf node_modules && rm yarn.lock
  2. yarn cache clean
  3. yarn
  4. react-native run-ios
  5. react-native run-android

If you're using npm

  1. rm -rf node_modules && rm package-lock.json
  2. npm cache clean --force
  3. npm install
  4. react-native run-ios
  5. react-native run-android

If bundler doesn't automatically start Simply run yarn start or npm start in the Example folder.

Don't forget to bump project and example versions in package.json whenever you submit a PR.

Rate & Review

Great Documentation0
Easy to Use0
Highly Customizable0
Bleeding Edge0
Responsive Maintainers0
Poor Documentation0
Hard to Use0
Unwelcoming Community0
Andre de Senne48 Ratings51 Reviews
2 months ago

Excellent library! It really get's the deck feeling and has a more complex UX than react-native-snap-carousel. Of course the functionality can be separated from use cases from both libraries, but I still think the replacement is worth a try if you are trying to cheer up the user experience from regular image displays.



No alternatives found


No tutorials found
Add a tutorial