Open-source project
glepur/react-native-swipe-gestures avatar
glepur/react-native-swipe-gestures

react-native-swipe-gestures turns a PanResponder into four named swipes

4-directional swipe gestures for react-native

606 stars153 forksJavaScriptMIT

At a glance

What is it?
react-native-swipe-gestures is a small React Native component that recognises swipes in four directions and reports them through separate callbacks, with thresholds for velocity and offset. It is a thin wrapper rather than a gesture engine, and it has no release notes to consult.
Who is it for?
Adopt react-native-swipe-gestures when you need one screen to react to a swipe in a known direction and you want a single wrapper instead of writing PanResponder logic. Skip it if you need continuous tracking, velocity-based paging, or a gesture system that can be composed with other responders, since this component only reports a completed swipe.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 90 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A wrapper over PanResponder, not a gesture engine

react-native-swipe-gestures is a React Native component for handling swipe gestures in the up, down, left and right directions. The mechanism is not hidden. The documentation describes the gesture state it hands you as the state received from PanResponder, so the component is a thin layer over React Native's own PanResponder rather than a separate gesture system. That is the whole design in one sentence, and it cuts both ways. On the good side, there is no new native dependency, no worklet bridge, and nothing to configure in a native project. On the other side, you get direction detection and a callback, not a gesture graph. There is no way to receive updates while the finger is still moving, no way to cancel a gesture that has already started, and no notion of a gesture competing with a parent scroll view. The repository layout matches the claim: a single `index.js`, a `index.d.ts` for types, a `package.json`, a licence and a linter configuration, with no `src` directory and no example app.

The install is one npm command and a class component

Installation is a single dependency, added with `npm i -S react-native-swipe-gestures`, and the README shows the import as the first thing you need.

javascript
import React, {Component} from 'react';
import {View, Text} from 'react-native';
import GestureRecognizer, {swipeDirections} from 'react-native-swipe-gestures';

The package exports a default component and a named export called `swipeDirections`. The sample implementation is a class component that keeps its gesture state in `this.state`, with a text string, a gesture name and a background colour. The four directional handlers each set the text, and a combined `onSwipe` handler receives the gesture name and the state together.

javascript
  onSwipeUp(gestureState) {
    this.setState({myText: 'You swiped up!'});
  }

  onSwipeDown(gestureState) {
    this.setState({myText: 'You swiped down!'});
  }

The combined handler is where the direction constants are used, and the switch on the gesture name is what lets one handler colour the screen differently per direction.

javascript
  onSwipe(gestureName, gestureState) {
    const {SWIPE_UP, SWIPE_DOWN, SWIPE_LEFT, SWIPE_RIGHT} = swipeDirections;
    this.setState({gestureName: gestureName});
    switch (gestureName) {
      case SWIPE_UP:
        this.setState({backgroundColor: 'red'});
        break;

Note that the directional callbacks are optional. The component props list in the sample shows all five wired up, but you can supply only the ones you need.

Three thresholds decide when a swipe counts

The config object is optional, and the three values that matter are the thresholds. `velocityThreshold` defaults to 0.3 and is the velocity that has to be breached for a swipe to trigger, measured on the `vx` and `vy` properties of the gesture state. `directionalOffsetThreshold` defaults to 80 and is the absolute offset that should not be breached, using `dy` for a horizontal swipe and `dx` for a vertical one, which is the mechanism that keeps a mostly-horizontal drag from firing a left or right swipe. `gestureIsClickThreshold` defaults to 5 and is the absolute distance that has to be breached for the gesture not to be considered a click. The sample sets the first two and leaves the third alone.

javascript
    const config = {
      velocityThreshold: 0.3,
      directionalOffsetThreshold: 80
    };

Those defaults are not neutral. An offset threshold of 80 is a large fraction of a phone screen width, so on a narrow layout a deliberate horizontal swipe may not register, and on a tablet it registers too eagerly. The velocity threshold of 0.3 is likewise a value that was chosen against some particular movement, not a physical constant. If your swipe is a short flick in a list row, you will want to lower the offset threshold; if it is a deliberate full-screen gesture, you may want to raise it. Nothing in the documentation explains how the two interact, so treat tuning as empirical work on a real device.

The component is a container, and it swallows the touch

The render method shows the shape of the component, and it is worth reading carefully because it decides who receives the touch. `GestureRecognizer` is a wrapper that takes the style and the children, and the children in the sample are plain `Text` elements.

javascript
      <GestureRecognizer
        onSwipe={(direction, state) => this.onSwipe(direction, state)}
        onSwipeUp={(state) => this.onSwipeUp(state)}
        onSwipeDown={(state) => this.onSwipeDown(state)}
        onSwipeLeft={(state) => this.onSwipeLeft(state)}
        onSwipeRight={(state) => this.onSwipeRight(state)}
        config={config}
        style={{
          flex: 1,
          backgroundColor: this.state.backgroundColor
        }}
        >
        <Text>{this.state.myText}</Text>
        <Text>onSwipe callback received gesture: {this.state.gestureName}</Text>
      </GestureRecognizer>

Because the recognizer occupies the whole area and owns the responder, a `GestureRecognizer` that fills a screen will interfere with anything else that wants touches in the same region, a scroll view or a pressable in particular. The documentation does not describe a `shouldSetResponder` override, a `onMoveShouldSetPanResponder` prop, or any way to hand the gesture to a parent. That is the practical reason this library fits a dedicated screen better than a list. If you need a swipe inside a scrollable list, you will be fighting the responder system, and the honest answer is that this component was not built for that.

Version 1.0.5, a test script that fails on purpose

The package manifest is worth a close look because it says several things about the project. The version is 1.0.5, the main entry is `index.js` and the types point at `index.d.ts`, so TypeScript consumers get declarations from the package rather than needing `@types`. The licence is MIT and the author is named in the manifest. The test script is the telling part: it is `echo "Error: no test specified" && exit 1`, which is the npm default for a project with no test suite, left in place. The repository has no GitHub releases either, so there is no changelog to read and no published history of what changed between versions. The last push to the repository was on 2026-07-25, and the topic tags are gesture, gestures, react-native, swipe and touch. This is a small, stable-shaped library: a single file of implementation, one author, no test infrastructure. That is not automatically a problem for a component this narrow, but it does mean that when a new React Native release changes the responder behaviour, you will be reading `index.js` rather than a release note.

When a swipe is the wrong interaction

There is a class of problem this library cannot solve, and it is worth naming before you adopt it. A swipe gesture is a discrete, one-shot event: the finger goes down, moves in a direction, and the component reports a direction once. Anything that needs continuous feedback while the finger moves, such as a card that follows your thumb, a pull-to-refresh with a live progress indicator, or a pager that tracks the drag distance, needs the gesture state on every frame. The component exposes the PanResponder state to the callback, but only at the moment the swipe is recognised, not continuously, so you cannot drive an animated value from it. The same applies to velocity-based decisions. The thresholds tell the component when to fire, but the fired event is just a direction. If your design needs a value proportional to the drag, this library gives you a starting point and no data, and building that means writing the PanResponder handling yourself. In that case a direct PanResponder implementation, or a library built around Reanimated worklets, is the better fit.

Editorial conclusion

Adopt react-native-swipe-gestures when you need one screen to react to a swipe in a known direction and you want a single wrapper instead of writing PanResponder logic. Skip it if you need continuous tracking, velocity-based paging, or a gesture system that can be composed with other responders, since this component only reports a completed swipe. Before you rely on it, check the thresholds against your own layout, because the default directional offset of 80 and velocity of 0.3 are tuned for one particular screen size, and read the source of index.js, since the repository ships no test suite and no documented upgrade path.

Frequently asked questions

How do I install react-native-swipe-gestures?

Run `npm i -S react-native-swipe-gestures`, then import the default component and the `swipeDirections` named export. The package entry point is `index.js` and TypeScript declarations ship in `index.d.ts`.

What thresholds can I configure in react-native-swipe-gestures?

The optional `config` property accepts `velocityThreshold`, defaulting to 0.3, `directionalOffsetThreshold`, defaulting to 80, and `gestureIsClickThreshold`, defaulting to 5. The first two are set in the README example.

What does the onSwipe callback receive?

It receives the gesture name and the gesture state, where the name is one of the `swipeDirections` constants and the state is the object received from PanResponder. The directional callbacks such as onSwipeUp receive only the state.

Does react-native-swipe-gestures have tests?

No. The package manifest defines the test script as `echo "Error: no test specified" && exit 1`, the npm placeholder for a project with no test suite, and the repository has no GitHub releases or changelog.

Official sources

  1. glepur/react-native-swipe-gestures on GitHub
  2. Issues
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/glepur-react-native-swipe-gestures.svg)](https://hysenlabs.com/projects/glepur-react-native-swipe-gestures)

Was this useful?