React Native Reanimated
React Native Reanimated is a high-performance animation library for React Native, offering a powerful and flexible alternative to the built-in `Animated` API. It enables animations to run directly on the native UI thread, completely decoupling them from the JavaScript thread, which results in significantly smoother and more reliable user experiences, especially under heavy load or during complex interactions. The current stable version is 4.3.0, with frequent patch and minor updates. The library maintains a rapid release cadence, often introducing core infrastructure improvements via the tightly coupled `react-native-worklets` package, like the recent `Shareable` memory type. Key differentiators include its worklet-based architecture, allowing direct UI thread execution of JavaScript functions, and recent advancements such as CSS SVG animations for `Path`, `Image`, `LinearGradient`, `RadialGradient`, `Pattern`, and `Text` components, including advanced path morphing capabilities.
Common errors
-
Invariant Violation: `worklet` must be a function.
cause The Babel plugin is not processing your code correctly, meaning functions marked as worklets are not being recognized or transformed for UI thread execution.fixDouble-check that `react-native-reanimated/plugin` is correctly installed and listed as the *last* plugin in your `babel.config.js`. After modification, clear your Metro cache (`npx react-native start --reset-cache`) and rebuild your application. -
ERROR Invariant Violation: `new NativeReanimatedModule()` cannot be found. This typically happens when the native module is not linked correctly.
cause The native module for Reanimated is not properly linked or loaded into your React Native project, which often occurs after an initial installation, upgrade, or if the project configuration is incorrect.fixFor bare React Native projects, ensure `pod install` (iOS) or `npx react-native run-android` (Android) has been executed after installation. For Expo projects, you *must* use a custom development client (`expo prebuild` and `eas build --profile development`) as Reanimated is a native module. -
TypeError: Cannot read property 'value' of undefined at anonymous function
cause You are attempting to access the `.value` property of a `SharedValue` that is either not initialized, or is `undefined` because it was not correctly created with `useSharedValue` or passed down.fixEnsure that any variable you expect to be a `SharedValue` is properly initialized using `useSharedValue(initialValue)` before accessing its `.value` property. Verify correct prop drilling if passing shared values between components. -
Invariant Violation: Calling `toJSON` on the 'Reanimated' module is not supported.
cause This error typically occurs during Jest tests when the Reanimated native module is mocked incorrectly or not mocked at all, and a test tries to serialize it.fixConfigure Jest to mock `react-native-reanimated` properly. A common approach is to use `jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock'));` in your Jest setup file.
Warnings
- breaking Reanimated v2 (and subsequent major versions like v3 and v4) introduced a fundamentally new API centered around hooks and worklets, deprecating the imperative API from v1. Existing v1 code requires a full rewrite.
- gotcha Incorrect or missing Babel plugin configuration (`react-native-reanimated/plugin`) will prevent worklets from being correctly transformed and lead to runtime errors, as functions intended for the UI thread won't be recognized.
- deprecated The `useAnimatedKeyboard` hook has been deprecated and its functionality is now intended to be handled by the external `react-native-keyboard-controller` library.
- gotcha Expo Go does not support static feature flags, which are integral to certain optimizations within Reanimated. Attempting to use these flags in Expo Go might result in unexpected behavior or build failures.
- breaking Stricter peer dependency validation for `react-native` and `react-native-worklets` can cause build failures or runtime crashes if versions are mismatched.
Install
-
npm install react-native-reanimated -
yarn add react-native-reanimated -
pnpm add react-native-reanimated
Imports
- useSharedValue
import { SharedValue } from 'react-native-reanimated';import { useSharedValue } from 'react-native-reanimated'; - useAnimatedStyle
import { AnimatedStyle } from 'react-native-reanimated';import { useAnimatedStyle } from 'react-native-reanimated'; - Animated
const Animated = require('react-native-reanimated');import Animated, { useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated'; - runOnJS
import { runOnJS } from 'react-native-reanimated';
Quickstart
import React from 'react';
import { Button, View, StyleSheet } from 'react-native';
import Animated, {
useSharedValue,
useAnimatedStyle,
withSpring,
} from 'react-native-reanimated';
const Box = () => {
const offset = useSharedValue(0);
const animatedStyles = useAnimatedStyle(() => {
// Animations run on the UI thread here
return {
transform: [
{ translateX: withSpring(offset.value * 255) },
],
};
});
const handlePress = () => {
offset.value = Math.random(); // Update shared value from JS thread
};
return (
<View style={styles.container}>
<Animated.View style={[styles.box, animatedStyles]} />
<Button onPress={handlePress} title="Move" />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
box: {
width: 100,
height: 100,
backgroundColor: 'purple',
borderRadius: 10,
marginBottom: 20,
},
});
export default Box;