Using Expo + Reanimated for Smooth UI Animations
Introduction
React Native Reanimated delivers high-performance animations by running animations on the UI thread. This guide covers setup and building declarative animations in Expo apps.
Prerequisites
- Expo SDK 47+
- Basic Expo setup
Step 1: Install Reanimated
expo install react-native-reanimated react-native-gesture-handler
Step 2: Configure Babel
Add plugin to babel.config.js
:
module.exports = function (api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
plugins: ["react-native-reanimated/plugin"],
};
};
Step 3: Enable Gesture Handler
In entry.js
:
import "react-native-gesture-handler";
import "expo-router/entry";
Step 4: Create Animated Component
Create components/AnimatedBox.tsx
:
import { View, StyleSheet } from 'react-native';
import Animated, { useSharedValue, useAnimatedStyle, withSpring, withTiming } from 'react-native-reanimated';
import { TapGestureHandler } from 'react-native-gesture-handler';
import { useState } from 'react';
export default function AnimatedBox() {
const offset = useSharedValue(0);
const [toggled, setToggled] = useState(false);
const animatedStyles = useAnimatedStyle(() => ({
transform: [
{ translateY: withSpring(offset.value) },
{ rotate:
withTiming(toggled ? '0deg' : '360deg', { duration: 1000 })
}
],
backgroundColor: withTiming(toggled ? 'tomato' : 'skyblue'),
}));
return (
<TapGestureHandler onActivated={() => {
offset.value = toggled ? 0 : 150;
setToggled(!toggled);
}}>
<Animated.View style={[styles.box, animatedStyles]} />
</TapGestureHandler>
);
}
const styles = StyleSheet.create({
box: {
width: 100,
height: 100,
alignSelf: 'center',
marginTop: 100,
},
});
Step 5: Integrate into App
Update app/index.js
:
import AnimatedBox from "@/components/AnimatedBox";
export default function Home() {
return <AnimatedBox />;
}
Summary
Expo + Reanimated empowers you to create fluid, native-feeling animations that run on the UI thread, ensuring smooth performance even under load.