SkillByAIOpen interactive version →

Lesson 20 / 25

Animations

Animated versus Reanimated.

Two animation libraries

The built-in Animated API drives values over time with Animated.timing, Animated.spring and composition helpers. Setting useNativeDriver: true sends the animation to the native side so it continues smoothly even when JavaScript is busy, but only for non-layout properties such as transform and opacity. react-native-reanimated goes further: animation logic runs in small JavaScript functions called worklets on the UI thread, using shared values, useAnimatedStyle and helpers such as withTiming and withSpring. It supports gesture-driven and layout animations and pairs with react-native-gesture-handler. Reanimated has significant version differences (for example newer major versions require the New Architecture); check the docs for your version. LayoutAnimation is another built-in option for simple layout changes.

A fade-in with each library

Animated with the native driver, then Reanimated.

import { useEffect, useRef } from "react";
import { Animated } from "react-native";
import Reanimated, { useSharedValue, useAnimatedStyle, withTiming } from "react-native-reanimated";

// 1. built-in Animated
export function FadeInAnimated({ children }: { children: React.ReactNode }) {
  const opacity = useRef(new Animated.Value(0)).current;
  useEffect(() => {
    Animated.timing(opacity, { toValue: 1, duration: 300, useNativeDriver: true }).start();
  }, [opacity]);
  return <Animated.View style={{ opacity }}>{children}</Animated.View>;
}

// 2. Reanimated
export function FadeInReanimated({ children }: { children: React.ReactNode }) {
  const opacity = useSharedValue(0);
  useEffect(() => {
    opacity.value = withTiming(1, { duration: 300 });
  }, [opacity]);
  const style = useAnimatedStyle(() => ({ opacity: opacity.value }));
  return <Reanimated.View style={style}>{children}</Reanimated.View>;
}

Respect reduced motion

Some users turn on reduced motion in system settings. Check it (AccessibilityInfo or Reanimated helpers) and shorten or skip large animations.

A recorded dance versus a live caller

With the native driver or worklets, the dancer knows the whole routine in advance. JS-driven animation is a caller shouting each step; if the caller gets distracted, the dancer freezes.

Quick check: What does useNativeDriver: true in the Animated API do?

  • Allows animating any layout property such as width
  • Runs the animation on the native side so a busy JS thread does not stutter it
  • Converts the app to native code
  • Disables the animation on Android
Answer

Runs the animation on the native side so a busy JS thread does not stutter it — It works for properties like transform and opacity.