React Native · Mobile UI at native speed

How does Reanimated run animations on the UI thread?

Hardreanimatedworkletsui threadUpdated Oct 2026
Quiz this track

Short answer

Reanimated compiles worklets to run on the UI thread, where they read shared values and update native view props directly. That avoids a JS-thread round trip for every animation frame.

A worklet is a JavaScript function that Reanimated can execute on the UI runtime. Shared values are references that both threads can read and write. useAnimatedStyle creates a style that is recalculated on the UI thread whenever a shared value it depends on changes.

tsx
import { Pressable } from "react-native";
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from "react-native-reanimated";

export function Expandable({ children }: { children: React.ReactNode }) {
  const open = useSharedValue(0);
  const style = useAnimatedStyle(() => ({
    opacity: open.value,
    transform: [{ scaleY: 0.9 + open.value * 0.1 }],
  }));

  return (
    <>
      <Pressable onPress={() => { open.value = withTiming(open.value === 1 ? 0 : 1, { duration: 200 }); }}>
        <Animated.Text>Toggle</Animated.Text>
      </Pressable>
      <Animated.View style={style}>{children}</Animated.View>
    </>
  );
}
The animation runs from the shared value update, without a React render on the JS thread.

What to watch for

  • Worklets capture values at creation time; use shared values for changing data
  • Do not call JS-only APIs such as fetch or setState inside a worklet
  • useAnimatedStyle must read shared values to be reactive
  • runOnJS is required to call JavaScript from the UI runtime
  • Layout animations can conflict with manual transforms; test the combination

Reanimated is not automatically faster for every animation. The gain comes from avoiding cross-thread work per frame. If an animation depends on data that must be fetched or computed on the JS thread, the bottleneck remains. Keep the animated state minimal and derive it on the UI side.

Debugging worklets is different from normal JavaScript. Use console.log inside a worklet only during development, and check the Reanimated logs when a shared value does not update as expected.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1What is a worklet?
  2. 2When do you need runOnJS?
  3. 3Why does a captured variable not update inside a worklet?
  4. 4What is the difference between useAnimatedStyle and a normal style?

Say it in the interview

Reanimated runs worklets on the UI thread, and shared values let that thread read and write animation state without a JS round trip. useAnimatedStyle recalculates the style on the UI runtime when its shared values change. I keep worklets free of JS-only work, use runOnJS when I must call back into JavaScript, and remember that captured values are snapshots rather than live references.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live React Native mock interview and get scored feedback on depth, clarity and confidence.