react-native-gesture-handler, react-native-modal, and react-native-raw-bottom-sheet are libraries commonly used in React Native applications to handle user interactions and present content in overlays. react-native-gesture-handler provides a robust system for handling touch-based gestures with native-backed performance, enabling smooth animations and complex gesture recognition. react-native-modal offers a customizable modal component that extends the built-in React Native Modal with additional features like animation, backdrop interaction, and device-specific adaptations. react-native-raw-bottom-sheet is a lightweight implementation of a bottom sheet UI pattern, allowing content to slide up from the bottom of the screen, typically used for menus, actions, or supplementary information.
When building polished React Native apps, you often need more than basic buttons and views. Presenting overlays, capturing gestures, and animating transitions are common requirements. The packages react-native-gesture-handler, react-native-modal, and react-native-raw-bottom-sheet each solve different parts of this puzzle. Let’s break down their roles, capabilities, and trade-offs.
react-native-gesture-handler is not a UI component — it’s a gesture engine. It gives you access to native gesture recognizers (like pan, pinch, and tap) that run off the main JavaScript thread, enabling buttery-smooth interactions even during heavy UI work. It’s the backbone for libraries like React Navigation’s swipe gestures and Reanimated-driven animations.
// react-native-gesture-handler: Pan gesture example
import { GestureDetector, Gesture } from 'react-native-gesture-handler';
import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
function DraggableBox() {
const offsetX = useSharedValue(0);
const offsetY = useSharedValue(0);
const panGesture = Gesture.Pan()
.onChange((event) => {
offsetX.value += event.changeX;
offsetY.value += event.changeY;
});
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: offsetX.value }, { translateY: offsetY.value }]
}));
return (
<GestureDetector gesture={panGesture}>
<Animated.View style={[{ width: 100, height: 100, backgroundColor: 'blue' }, animatedStyle]} />
</GestureDetector>
);
}
react-native-modal is a drop-in replacement for React Native’s built-in Modal, but with better defaults and more customization. It handles backdrop taps, hardware back button (Android), and cross-platform animations out of the box.
// react-native-modal: Basic usage
import Modal from 'react-native-modal';
function ConfirmationModal({ isVisible, onConfirm, onCancel }) {
return (
<Modal isVisible={isVisible} onBackdropPress={onCancel}>
<View style={{ padding: 20, backgroundColor: 'white', borderRadius: 10 }}>
<Text>Are you sure?</Text>
<Button title="Yes" onPress={onConfirm} />
<Button title="No" onPress={onCancel} />
</View>
</Modal>
);
}
react-native-raw-bottom-sheet provides a minimal bottom sheet component that slides up from the bottom. It supports basic snapping and gesture dismissal but lacks advanced features found in more mature alternatives.
// react-native-raw-bottom-sheet: Simple bottom sheet
import BottomSheet from 'react-native-raw-bottom-sheet';
function ActionSheet({ ref }) {
return (
<BottomSheet ref={ref}>
<View style={{ padding: 20 }}>
<Text>Choose an option</Text>
<Button title="Option 1" />
<Button title="Option 2" />
</View>
</BottomSheet>
);
}
// Usage elsewhere:
// sheetRef.current.open();
react-native-gesture-handler requires native linking (automatic via autolink in modern React Native) and must wrap your app root with GestureHandlerRootView on Android for proper behavior.
// App.js – required setup
import { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
{/* Rest of your app */}
</GestureHandlerRootView>
);
}
react-native-modal is pure JavaScript and has no native dependencies. It works immediately after installation and doesn’t require special setup beyond importing and using it.
react-native-raw-bottom-sheet also has no native dependencies, but it internally uses react-native-gesture-handler for its swipe-to-dismiss feature. This means you still need to install and configure react-native-gesture-handler even if you don’t use it directly elsewhere.
You want rows that can be swiped left to reveal delete/archive actions.
react-native-gesture-handlerreact-native-swipe-list-view are built on top of it.// Simplified swipeable item using RNGH
const translateX = useSharedValue(0);
const pan = Gesture.Pan()
.onUpdate((e) => {
translateX.value = Math.max(-100, Math.min(0, e.translationX));
})
.onEnd((e) => {
if (e.velocityX < -1000 || translateX.value < -50) {
// Snap open
translateX.value = withSpring(-100);
} else {
// Snap closed
translateX.value = withSpring(0);
}
});
You need a centered modal with fade-in animation and backdrop dimming.
react-native-modal<Modal
isVisible={showLogin}
animationIn="fadeIn"
animationOut="fadeOut"
backdropOpacity={0.6}
onBackdropPress={() => setShowLogin(false)}
>
<LoginForm />
</Modal>
You want a panel that slides up with sharing options (email, SMS, etc.).
react-native-raw-bottom-sheet@gorhom/react-native-bottom-sheet instead.As of the latest review:
react-native-gesture-handler is actively maintained by Software Mansion and is a de facto standard in the React Native ecosystem. It’s used in production by thousands of apps.react-native-modal is stable, widely adopted, and receives periodic updates. It’s safe for production use.react-native-raw-bottom-sheet shows signs of abandonment: the last npm publish was years ago, GitHub issues are unaddressed, and it lacks compatibility with newer React Native versions. Avoid in new projects.Yes — and often they should. For example, you might use react-native-modal to present a form, and inside that form, use react-native-gesture-handler to build a custom slider or draggable element. Similarly, a well-maintained bottom sheet library (not raw-bottom-sheet) would rely on react-native-gesture-handler under the hood.
However, react-native-raw-bottom-sheet already bundles its own gesture logic, so layering additional gesture handlers inside it may lead to conflicts or unexpected behavior.
| Feature | react-native-gesture-handler | react-native-modal | react-native-raw-bottom-sheet |
|---|---|---|---|
| Primary Role | Gesture engine | Animated modal overlay | Basic bottom sheet |
| Native Dependencies | Yes | No | Yes (via RNGH) |
| Production Ready | ✅ Yes | ✅ Yes | ❌ No (unmaintained) |
| Animation Support | Via Reanimated integration | Built-in (fade, slide, etc.) | Limited (basic slide) |
| Accessibility | Full support | Good support | Poor / unverified |
| Use When… | Building custom gestures/animations | Need reliable modal dialogs | Prototyping only (avoid in prod) |
react-native-gesture-handler. It’s foundational.react-native-modal is the go-to for simple, reliable overlays.react-native-raw-bottom-sheet. Instead, evaluate actively maintained alternatives like @gorhom/react-native-bottom-sheet, which offers better performance, accessibility, and feature completeness.Don’t treat these as interchangeable — they solve different layers of the UI interaction stack. Use them together where appropriate, but always verify maintenance status before committing to a dependency in production.
Choose react-native-gesture-handler when you need high-performance, native-backed gesture recognition for complex interactions like drag-and-drop, swipeable lists, or custom animated components. It’s essential for integrating with libraries like Reanimated and is the foundation for many advanced UI patterns in React Native. Avoid it if your app only uses basic touch events handled by standard onPress props.
Choose react-native-modal when you need a flexible, animated modal dialog that works consistently across iOS and Android with minimal setup. It’s ideal for confirmation dialogs, onboarding flows, or temporary full-screen overlays where you want control over animations, backdrop behavior, and accessibility. Don’t use it if you require a bottom sheet-style presentation — that’s better served by dedicated bottom sheet libraries.
Choose react-native-raw-bottom-sheet if you need a simple, dependency-light bottom sheet with basic snap points and gesture support without heavy theming or complex state management. It’s suitable for small projects or prototypes where you want quick implementation without pulling in larger libraries like @gorhom/react-native-bottom-sheet. However, note that this package appears unmaintained and lacks advanced features like nested scrolling or dynamic content resizing, so avoid it in production apps requiring robustness.
React Native Gesture Handler provides native-driven gesture management APIs for building best possible touch-based experiences in React Native.
With this library gestures are no longer controlled by the JS responder system, but instead are recognized and tracked in the UI thread. It makes touch interactions and gesture tracking not only smooth, but also dependable and deterministic.
Check getting started section of our docs for the detailed installation instructions.
Check out our dedicated documentation page for info about this library, API reference and more: https://docs.swmansion.com/react-native-gesture-handler/docs/
If you want to play with the API but don't feel like trying it on a real app, you can run the example project. Clone the repo, go to the example folder and run:
yarn install
Run yarn start to start the metro bundler
Run yarn android or yarn ios (depending on which platform you want to run the example app on).
You will need to have an Android or iOS device or emulator connected.
react-native-gesture-handler supports the three latest minor releases of react-native.
| version | react-native version |
|---|---|
| 2.28.0+ | 0.79.0+ |
| 2.26.0+ | 0.78.0+ |
| 2.25.0+ | 0.76.0+ |
| 2.24.0+ | 0.75.0+ |
| 2.21.0+ | 0.74.0+ |
| 2.18.0+ | 0.73.0+ |
| 2.16.0+ | 0.68.0+ |
| 2.14.0+ | 0.67.0+ |
| 2.10.0+ | 0.64.0+ |
| 2.0.0+ | 0.63.0+ |
It may be possible to use newer versions of react-native-gesture-handler on React Native with version <= 0.59 by reverse Jetifying. Read more on that here https://github.com/mikehardy/jetifier#to-reverse-jetify--convert-node_modules-dependencies-to-support-libraries
Gesture handler library is licensed under The MIT License.
This project has been build and is maintained thanks to the support from Shopify, Expo.io and Software Mansion
Join the Software Mansion Community Discord to chat about Gesture Handler or other Software Mansion libraries.
Since 2012 Software Mansion is a software agency with experience in building web and mobile apps. We are Core React Native Contributors and experts in dealing with all kinds of React Native issues. We can help you build your next dream product – Hire us.