Gesture handling in React Native with react-native-gesture-handler

Touch and gesture interactions are the core of great mobile UX. If your gestures feel laggy or inconsistent, users will feel it immediately. In this guide, you will learn how to implement smooth, native-feel gestures with react-native-gesture-handler using modern APIs, plus the setup steps that avoid the most common pitfalls.
If you want to start from a production-ready foundation, explore our React Native templates and ship your next app faster.
Mega Bundle Sale is ON! Get ALL of our React Native codebases at 90% OFF discount ๐ฅ
Get the Mega BundleInstallationโ
Expoโ
expo install react-native-gesture-handler
React Native CLIโ
yarn add react-native-gesture-handler
Then ensure your entry file (e.g., index.js) imports the library before any other imports:
import "react-native-gesture-handler";
Finally, wrap your app in GestureHandlerRootView:
import React from "react";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import App from "./App";
export default function Root() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<App />
</GestureHandlerRootView>
);
}
If you plan to animate gestures smoothly, install Reanimated as well:
yarn add react-native-reanimated
The modern gesture API (recommended)โ
The new Gesture API works great with Reanimated and keeps animations on the UI thread for smooth performance.
Tap gesture (press effect)โ
import React from "react";
import { View, Text } from "react-native";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from "react-native-reanimated";
export default function TapCard() {
const scale = useSharedValue(1);
const tap = Gesture.Tap()
.onBegin(() => {
scale.value = 0.96;
})
.onFinalize(() => {
scale.value = withSpring(1);
});
const style = useAnimatedStyle(() => ({
transform: [{ scale: scale.value }],
}));
return (
<GestureDetector gesture={tap}>
<Animated.View style={[{ padding: 16, backgroundColor: "#111", borderRadius: 12 }, style]}>
<Text style={{ color: "#fff" }}>Tap me</Text>
</Animated.View>
</GestureDetector>
);
}
Pan gesture (drag a card)โ
import React from "react";
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from "react-native-reanimated";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
export default function DraggableCard() {
const x = useSharedValue(0);
const y = useSharedValue(0);
const pan = Gesture.Pan()
.onChange((e) => {
x.value += e.changeX;
y.value += e.changeY;
})
.onEnd(() => {
x.value = withSpring(0);
y.value = withSpring(0);
});
const style = useAnimatedStyle(() => ({
transform: [{ translateX: x.value }, { translateY: y.value }],
}));
return (
<GestureDetector gesture={pan}>
<Animated.View style={[{ width: 160, height: 120, backgroundColor: "#0f172a", borderRadius: 16 }, style]} />
</GestureDetector>
);
}
Working with ScrollView and nested gesturesโ
When gestures compete (e.g., a card inside a ScrollView), use simultaneousWithExternalGesture or requireExternalGestureToFail to control priority:
const scroll = Gesture.Native();
const pan = Gesture.Pan().simultaneousWithExternalGesture(scroll);
This keeps your drag interactions smooth without blocking the main scroll.
Performance tipsโ
- Keep logic inside gesture callbacks light. Heavy work should be offloaded or deferred.
- Prefer Reanimated values (
useSharedValue) for animation-driven interactions. - Only use
runOnJSwhen you must update React state.
Mega Bundle Sale is ON! Get ALL of our React Native codebases at 90% OFF discount ๐ฅ
Get the Mega BundleTroubleshootingโ
"GestureHandlerRootView is not found"
Make sure your app is wrapped with GestureHandlerRootView and that the library import is at the top of your entry file.
Gestures feel laggy
Check that you are using the new Gesture API with Reanimated, not JS-based animated values.
Touch conflicts in lists
Use simultaneousWithExternalGesture or require the scroll gesture to fail before your pan begins.
Looking for a custom mobile application?
Our team of expert mobile developers can help you build a custom mobile app that meets your specific needs.
Get in TouchConclusionโ
The best mobile apps feel effortless because their gestures are smooth, native, and predictable. With react-native-gesture-handler, you can build interactions that feel at home on both iOS and Android.
If you want to ship faster, start from a production-ready codebase with our React Native templates.
Explore related templatesโ
- React Native Social Network
- React Native Dating App
- Food Delivery App
- Short-Video (TikTok) Clone
- AI Chat App (ChatGPT template)
Or get everything at once with the All Access pass: All Access - Mega Bundle