Skip to content

t1k:rn:performance:animations

FieldValue
Moduleperformance
Version1.6.3
Effortmedium
Tools

Keywords: animations, gesture handler, layout animations, react native, reanimated, shared transitions

/t1k:rn:performance:animations

import Animated, {
useSharedValue, useAnimatedStyle, withSpring, withTiming,
runOnJS, useAnimatedGestureHandler,
} from 'react-native-reanimated';
// All worklet code runs on UI thread — never access JS state directly
function PressableCard() {
const scale = useSharedValue(1);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ scale: scale.value }],
}));
return (
<Pressable
onPressIn={() => { scale.value = withSpring(0.95); }}
onPressOut={() => { scale.value = withSpring(1); }}
>
<Animated.View style={[styles.card, animatedStyle]} />
</Pressable>
);
}
import { GestureDetector, Gesture } from 'react-native-gesture-handler';
const pan = Gesture.Pan()
.onUpdate((e) => {
translateX.value = e.translationX;
translateY.value = e.translationY;
})
.onEnd(() => {
translateX.value = withSpring(0);
translateY.value = withSpring(0);
});
return <GestureDetector gesture={pan}><Animated.View style={animStyle} /></GestureDetector>;
// Shared transition between screens
import { SharedTransition, withSpring } from 'react-native-reanimated';
const transition = SharedTransition.custom((values) => ({
width: withSpring(values.targetWidth),
height: withSpring(values.targetHeight),
}));
// Screen A
<Animated.Image sharedTransitionTag="hero-image" sharedTransitionStyle={transition} />
// Screen B
<Animated.Image sharedTransitionTag="hero-image" sharedTransitionStyle={transition} />
import { FadeIn, FadeOut, SlideInRight, Layout } from 'react-native-reanimated';
<Animated.View entering={FadeIn.duration(300)} exiting={FadeOut} layout={Layout.springify()}>
<Text>Animated content</Text>
</Animated.View>
  • Worklets run on UI thread — never call JS functions directly, use runOnJS()
  • useSharedValue for animated values — never useState for animation state
  • Wrap root in <GestureHandlerRootView style={{ flex: 1 }}> — required for Gesture Handler
  • Use withSpring for natural feel, withTiming for precise duration control
  • 'worklet' directive required for custom worklet functions called from animated styles
  • Shared transitions require both screens to use same sharedTransitionTag
  • GestureHandlerRootView must be outermost — before SafeAreaProvider and navigation
  • Layout animations on Android require enableExperimentalLayoutAnimation() in older RN versions