Understanding the JS Bridge Problem

Standard Animated API sends 60 messages per second across the bridge. It causes dropped frames if the JS thread is busy. This is React Native's fundamental performance bottleneck—every animation frame must travel from JavaScript to the native layer and back.

The bridge is asynchronous by design, which means:

  • Queue Delays: Messages queue up when JS thread is busy
  • Serialization Overhead: Data must be serialized/deserialized
  • Dropped Frames: 60 FPS requires 16ms per frame—bridge delays cause jank
  • Memory Overhead: Bridge communication has significant memory cost

When your app performs heavy computations, makes network calls, or processes large data sets, the JS thread blocks, and animations stutter. This is why Reanimated was created—to eliminate bridge communication for animations.

How Reanimated Works: UI Thread Execution

It runs animation logic directly on the UI thread (Native). Even if JS is blocked, your scroll or drag keeps moving smoothly. Reanimated 3 runs animations entirely on the native side, completely bypassing the JavaScript bridge.

Here's how it works:

  • Native Worklets: Animation logic runs in a separate VM on the UI thread
  • Synchronous Updates: Frame updates happen without bridge communication
  • Gesture Continuity: User gestures remain responsive even when JS is blocked
  • 60 FPS Guaranteed: Animations maintain smooth frame rates independently
Reanimated solves React Native's animation performance problem by moving computation to where it belongs—the native layer.

Shared Values: State Management for Animations

Similar to Animated.Value but accessible from both JS and UI threads. useSharedValue(0) creates a mutable value for animations. Shared values are the core of Reanimated's architecture:

  • Cross-Thread Access: Read/write from both JS and UI threads
  • Type Safety: TypeScript support for value types
  • Performance: Zero-copy access on the UI thread
  • Observability: Can watch for changes from JS thread

Unlike Animated.Value, shared values persist their state and can be accessed from worklets running on the UI thread. This enables smooth animations even when the JS thread is busy with other tasks.

Worklets: JavaScript Functions on the UI Thread

Tiny JavaScript functions that are moved to a separate VM on the UI thread. Marked with 'worklet'. They drive the animation logic synchronously. Worklets are the secret sauce:

  • Automatic Detection: Functions using 'worklet' directive are moved to UI thread
  • Limited API: Can only use subset of JavaScript features
  • Synchronous Execution: No async/await, no promises—pure calculations
  • Performance: Execute in the same thread as UI rendering

Worklets enable you to write animation logic in JavaScript but execute it on the native thread. This gives you the best of both worlds: JavaScript's developer experience with native performance.

Gesture Handler Integration for Smooth Interactions

Reanimated pairs naturally with react-native-gesture-handler. Map gesture events directly to shared values for 1:1 interaction. This integration creates the smoothest user experiences:

  • Direct Mapping: Gesture events update shared values directly
  • No Bridge Calls: Entire gesture flow runs on UI thread
  • 60 FPS Gestures: Buttery smooth dragging, pinching, and swiping
  • Simultaneous Gestures: Support for multiple simultaneous interactions

The combination of Reanimated and Gesture Handler enables building apps that feel truly native. Complex interactions like pull-to-refresh, swipeable cards, and pinch-to-zoom become effortless.

Layout Animations: Automatic Transitions

Reanimated 3 makes entering/exiting/layout changes easy. Just add entering={FadeIn} to a view. No manual height calculation needed. Layout animations handle complex scenarios automatically:

  • Entering Animations: FadeIn, SlideIn, ZoomIn—apply to new views
  • Exiting Animations: FadeOut, SlideOut—handle view removal
  • Layout Animations: Automatically animate position/size changes
  • Shared Element Transitions: Smooth transitions between screens

Previous versions required manual measurement and calculation. Reanimated 3 handles all of this automatically, making beautiful animations accessible to all developers.

Debugging UI Thread Animations

Debugging on the UI thread is tricky. Rely on console.log from within worklets (Reanimated supports this) to trace values. Here are debugging strategies:

  • Logging: console.log works in worklets for tracing values
  • DevTools: Use Flipper's Reanimated plugin for visualization
  • Performance Monitor: Track FPS during animations
  • Timeline: Use React DevTools to see when worklets execute

Remember: debugging worklets requires different approaches than regular JavaScript. Values update on a different thread, so traditional breakpoints won't work. Use logging and visualization tools instead.

When performance issues occur, check if animations are actually running on the UI thread. If they're falling back to the JS thread, you'll see frame drops. Use Reanimated's runOnUI helper to ensure code executes on the correct thread.