React Native reanimated - Animation
React Native Reanimated has emerged as the de facto standard for building fluid, high-performance animations in React Native applications. Unlike the legacy Animated API, which often struggles with jank and off-main‑thread synchronization issues, Reanimated runs animations directly on the UI thread via JavaScript Interface (JSI) bindings, enabling silky‑smooth experiences even under heavy UI load. Whether you’re animating simple opacity changes or creating complex gesture‑driven interfaces, Reanimated provides a rich ecosystem of hooks, worklets, and utilities to bring your designs to life with minimal effort.
In this article, we’ll dive deep into React Native Reanimated—covering its core concepts, API fundamentals, advanced patterns, and best practices. By the end, you’ll have a solid understanding of how to harness Reanimated’s power to elevate your app’s interactivity and performance.
1. Why Reanimated? A Comparison with Animated
- Main‑Thread vs UI‑Thread
The legacy Animated library executes animations on the JavaScript thread, which can become blocked by heavy logic or network requests, leading to dropped frames. Reanimated, however, leverages JSI to schedule and run “worklets” directly on the UI thread, isolated from JavaScript, resulting in consistently smooth 60 fps animations. - Declarative Syntax
Reanimated’s hooks-based API (e.g., useAnimatedStyle, useSharedValue) offers a declarative paradigm that closely mirrors React’s component model, making code more readable and maintainable. - Gesture Integration
When paired with react-native-gesture-handler, Reanimated enables complex gesture‑driven interactions (e.g., drag‑to‑dismiss, swipeable lists) with minimal boilerplate. - Rich Animation Primitives
Functions like withTiming, withSpring, and withDecay allow you to express timing, spring, and decay animations out of the box, while utilities like interpolate, interpolateColor, and Easing empower detailed control over animation curves.
2. Installation and Setup
Installing Reanimated is straightforward. As of July 2025, the latest stable version is 3.18.0, published a month ago on npm (npm).
# Yarn yarn add react-native-reanimated # or npm npm install react-native-reanimated
Next, add the Babel plugin to enable Reanimated’s worklet transpilation. In your babel.config.js:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
'react-native-reanimated/plugin', // must be last
],
};Finally, rebuild your app:
# iOS cd ios && pod install && cd .. npx react-native run-ios # Android npx react-native run-android
With these steps, Reanimated will be ready to power your animations (docs.swmansion.com).
3. Core Concepts
3.1 Shared Values
A shared value is a mutable container for data that can be accessed from both JavaScript and UI‑thread worklets. Changes to shared values trigger worklet executions, enabling dynamic animations.
import { useSharedValue } from 'react-native-reanimated';
const progress = useSharedValue(0);3.2 Worklets
Worklets are functions annotated with the special comment "worklet" directive. They run on the UI thread and can read/write shared values, manipulate styles, and call other worklets.
runOnUI(() => {
'worklet';
progress.value = withTiming(1, { duration: 500 });
})();3.3 Animated Styles
Use the useAnimatedStyle hook to map shared values to view styles. The returned style object updates automatically when dependencies change.
import { useAnimatedStyle, withTiming } from 'react-native-reanimated';
const style = useAnimatedStyle(() => ({
opacity: withTiming(progress.value),
}));3.4 Gesture Handlers
When combined with react-native-gesture-handler, you can create animations that respond directly to user gestures.
import { PanGestureHandler } from 'react-native-gesture-handler';
import { useAnimatedGestureHandler, useSharedValue } from 'react-native-reanimated';
const translationX = useSharedValue(0);
const gestureHandler = useAnimatedGestureHandler({
onActive: (event) => {
translationX.value = event.translationX;
},
onEnd: () => {
translationX.value = withSpring(0);
},
});4. Animation Primitives
Reanimated provides high‑level functions for different animation types:
- withTiming: Smooth, time‑based animations.
progress.value = withTiming(1, { duration: 300 });- withSpring: Physics‑based spring animations.
translationY.value = withSpring(0, { damping: 20, stiffness: 90, });- withDecay: Momentum‑based decay animations, ideal for scroll inertia.
velocityX.value = withDecay({ velocity: gesture.velocityX });- withSequence and withDelay: Combine multiple animations sequentially or after a delay.
opacity.value = withSequence( withTiming(1, { duration: 200 }), withDelay(100, withTiming(0.5, { duration: 200 })) );
5. Advanced Patterns
5.1 Derived Values
Compute values based on one or more shared values with useDerivedValue. This is useful for chaining animations or computing complex transforms.
const doubleProgress = useDerivedValue(() => progress.value * 2);
5.2 Animated Props
useAnimatedProps lets you animate non‑style props, such as SVG path data or text attributes.
import Animated, { useAnimatedProps } from 'react-native-reanimated';
import { Text } from 'react-native';
const animatedProps = useAnimatedProps(() => ({
text: `${Math.round(progress.value * 100)}%`,
}));
<Animated.Text animatedProps={animatedProps} />;5.3 Layout Animations
Leverage Reanimated’s new layout animation API to animate view insertion, exit, and layout changes automatically.
import { Layout, FadeIn, FadeOut } from 'react-native-reanimated';
<Animated.View
entering={FadeIn.duration(300)}
exiting={FadeOut.duration(200)}
layout={Layout.springify()}
/>6. Gesture‑Driven Interactions
By integrating with react-native-gesture-handler, Reanimated makes it straightforward to build interactive components:
- Swipeable Cards: Use PanGestureHandler and shared values to track drag offsets, then apply rotation and translation transforms.
- Draggable Lists: Combine useAnimatedScrollHandler with withTiming to smoothly reorder items.
- Pinch‑to‑Zoom: Use PinchGestureHandler to capture scale and focal point, applying dynamic transforms.
const pinchHandler = useAnimatedGestureHandler({
onActive: (event) => {
scale.value = event.scale;
focalX.value = event.focalX;
focalY.value = event.focalY;
},
onEnd: () => {
scale.value = withSpring(1);
},
});7. Performance Considerations
- Minimize JS‑UI Traffic: Keep worklets self‑contained; avoid unnecessary callbacks to JavaScript.
- Batch Updates: Use batch to group multiple shared‑value updates into a single transaction.
- Debugging: Enable the Reanimated plugin’s debug mode with Reanimated.setConfig({ enableLayoutAnimations: true, setNow: true }) to visualize layout animations.
8. Support for React Native New Architecture
Reanimated 3.x fully supports the New Architecture (Fabric + TurboModules) in React Native 0.80 and above, ensuring compatibility with modern apps (GitHub). Nightly builds for Reanimated 4.0.0 are also available for testing cutting‑edge features alongside React Native’s new internals (Yarn).
9. Real‑World Use Cases
- Onboarding Screens: Smoothly animate transitions between tutorial pages, using layout animations for dynamic content.
- Interactive Charts: Animate data updates with withTiming while responding to pan and zoom gestures.
- Custom Pull‑to‑Refresh: Use withSpring to create elastic bounce effects and useAnimatedScrollHandler to trigger refresh logic.
10. Best Practices
- Isolate Complex Logic: Keep worklets small and focused—move heavy computations outside animation callbacks.
- Type Safety: Use TypeScript to type shared values and worklet parameters for better DX.
- Module Splitting: Lazily load animations in large apps to minimize startup overhead.
- Testing: Use snapshot tests combined with Jest’s fake timers for timing‑based animations; integrate E2E tests via Detox or Appium for gesture scenarios.
Conclusion
React Native Reanimated empowers developers to transcend the limitations of JavaScript‑threaded animations, offering an architecture that runs directly on the UI thread, rich animation primitives, and tight integration with gesture handling. From simple fades to intricate, gesture‑driven interfaces and layout transitions, Reanimated provides the building blocks to craft exceptional user experiences.
Whether you’re starting a new React Native project in 2025 or migrating existing screens to a more performant animation solution, Reanimated’s robust ecosystem and forward‑looking features make it an indispensable tool in your toolkit. Start experimenting today and unlock the full potential of UI‑thread animations!