Description:
React Native Reanimated Modal is an animated modal component for React Native applications.
It uses the standard React Native Modal component as its base to maintain a native look and feel across platforms.
The library integrates react-native-reanimated and react-native-gesture-handler to produce high-performance animations and interactive gestures.
Features
- ð Runs 60fps animations on the UI thread for optimal performance.
- ðĻ Supports fade, slide, and scale animations with configurable options.
- ð Offers interactive swipe-to-dismiss gestures for any direction.
- ðŠķ Has minimal dependencies which contributes to a smaller application bundle size.
- ðą Utilizes the native React Native Modal for platform consistency.
- ð§ Provides a highly customizable API through various props.
- ð Includes full TypeScript support for improved type safety.
- ð Integrates with React Navigation and supports multiple modal overlays.
Preview

How to Use It
1. Install the package with NPM/Yarn/PNPM/BUN.
npm install react-native-reanimated-modal2. This library requires react-native-reanimated and react-native-gesture-handler. You must install and configure these two packages in your project.
3. Wrap your application’s root component with gestureHandlerRootHOC.
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';
const App = () => {
// Your application components
};
export default gestureHandlerRootHOC(App);4. Import the modal and control its visibility with component state. The visible prop toggles its appearance, and the onHide callback updates the state when the modal closes.
import React, { useState } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import { Modal } from 'react-native-reanimated-modal';
const MyComponent = () => {
const [isModalVisible, setModalVisible] = useState(false);
return (
<View style={styles.container}>
<Button title="Open Modal" onPress={() => setModalVisible(true)} />
<Modal
visible={isModalVisible}
onHide={() => setModalVisible(false)}
>
<View style={styles.modalContent}>
<Text>This is a modal.</Text>
<Button title="Close" onPress={() => setModalVisible(false)} />
</View>
</Modal>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
modalContent: {
backgroundColor: 'white',
padding: 22,
borderRadius: 4,
alignItems: 'center',
},
});
export default MyComponent;5. You can customize the modal’s behavior with the following props:
General Props
visible: A boolean that controls whether the modal is visible or hidden. Defaults tofalse.children: TheReactNodecontent to be rendered inside the modal.closable: A boolean that determines if user actions (like a backdrop press or swipe) can close the modal. Defaults totrue.coverScreen: A boolean. If set totrue, the modal covers the entire screen without using the native Modal component, which is useful for managing multiple modal layers. Defaults tofalse.style: Custom styles for the root containerViewof the modal.contentContainerStyle: Custom styles applied to the animatedViewthat wraps yourchildren.
Configuration Props
animationConfig: An object or string to configure the entry and exit animations. It controls the animation type (fade,slide,scale), duration, and other specific parameters. Defaults to{ animation: 'fade', duration: 300 }.swipeConfig: An object to configure the swipe-to-dismiss gesture. You can enable or disable it, define swipe directions, set the swipe threshold, and customize the bounce-back animation.
Backdrop Props
hasBackdrop: A boolean that toggles the visibility of the backdrop. Defaults totrue.backdropColor: A string that sets the color of the backdrop. Defaults to'black'.backdropOpacity: A number between 0 and 1 that controls the opacity of the backdrop. Defaults to0.7.onBackdropPress: A callback function that is executed when the backdrop is pressed.renderBackdrop: A function that returns a customReactNodeto be used as the backdrop.
Event Props
onShow: A callback function that is executed when the modal’s “enter” animation is complete.onHide: A callback function that is executed when the modal’s “exit” animation is complete.
Testing Props
containerTestID: A string used to set thetestIDfor the modal’s root containerView.backdropTestID: A string used to set thetestIDfor the backdropPressablecomponent.contentTestID: A string used to set thetestIDfor the animatedViewthat wraps the modal’s content.
Native Modal Props
hardwareAccelerated(Android)navigationBarTranslucent(Android)statusBarTranslucent(Android)onOrientationChange(iOS)supportedOrientations(iOS)
A scale animation makes the modal grow into view.
<Modal
visible={isModalVisible}
onHide={() => setModalVisible(false)}
animationConfig={{
animation: 'scale',
duration: 500,
scaleFactor: 0.9,
}}
>
{/* Modal Content */}
</Modal>A slide animation moves the modal in from a specified direction. The direction property can define separate entry and exit animations.
<Modal
visible={isModalVisible}
onHide={() => setModalVisible(false)}
animationConfig={{
animation: 'slide',
duration: 400,
direction: {
start: 'down',
end: ['down', 'left']
}
}}
> {/* Modal Content */}
</Modal><Modal
visible={isModalVisible}
onHide={() => setModalVisible(false)}
swipeConfig={{
enabled: true,
directions: ['up', 'down'],
threshold: 120,
bounceSpringConfig: {
stiffness: 250,
dampingRatio: 0.6,
},
}}
>
{/* Modal Content */}
</Modal>Related Resources
- React Native Reanimated. The animation library that powers the modal’s performance. It provides tools for creating smooth animations that run on the native UI thread.
- React Native Gesture Handler. This library provides a more comprehensive gesture system for React Native. It is a required dependency for the modal’s swipe features.
FAQs
Q: Can I use multiple modals at the same time?
A: Yes. For handling multiple modal layers, especially with React Navigation, you can use the coverScreen={true} prop. On iOS, you can wrap your modals in the FullWindowOverlay component from react-native-screens for better layering.
Q: How do I disable the swipe-to-dismiss feature?
A: You can disable gestures by setting enabled: false inside the swipeConfig prop.
Q: Is it possible to create a full-screen modal?
A: Yes. To create a full-screen modal, you can apply flex: 1 to the contentContainerStyle prop and set hasBackdrop={false} to remove the background overlay.