React Native reanimated - Animation

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

  1. Isolate Complex Logic: Keep worklets small and focused—move heavy computations outside animation callbacks.
  2. Type Safety: Use TypeScript to type shared values and worklet parameters for better DX.
  3. Module Splitting: Lazily load animations in large apps to minimize startup overhead.
  4. 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!

#React Native Reanimated #React Native animations #Reanimated worklets #shared values #gesture‑handler #withTiming #withSpring #layout animations #JSI animations

Subscribe to our newsletter

12k+

Subscribers

Weekly

Frequency

Free

Always