Animated API: what it is, library features and operating principle

Author: IT Sectr Published: 2026-07-06 Reading time: 8 min

Animated API is a built-in declarative animation library in React Native that provides 60 FPS animation without burdening the JavaScript thread. According to the official React Native 0.76 (2025) documentation, Animated API supports useNativeDriver for all animation types, moving computations to the native thread via UI Manager. The library allows creating complex animation chains, interactive gestures, and interpolation of any style properties — from opacity to transformation.

Key Takeaways

  • Animated API — a declarative React Native animation library with native driver support
  • Animated.Value — a basic element that stores a numeric value and subscribes components to changes
  • useNativeDriver — an option that moves animation to the native thread for 60 FPS without jitter
  • Interpolation — a mechanism for converting numeric ranges into colors, angles, coordinates, and scale
  • Composition — sequential, parallel, and chained animations via sequence, parallel, and stagger

What is Animated API in React Native

Animated API is a declarative animation library built into the core of React Native, designed for creating smooth, performant animations in mobile applications. Unlike CSS animations in web development, Animated API works directly with the native UI thread via the JavaScript bridge or native driver. The library is built around the concept of Animated.Value — a container that stores a numeric value and automatically subscribes all dependent components to changes. When the value changes via Animated.timing or Animated.spring, the library calculates intermediate states without re-rendering React components, which is critical for maintaining 60 FPS. Animated API supports all style properties, including transform, opacity, width, height, top, left, and backgroundColor. React Native documentation recommends Animated API for all animation scenarios requiring high performance and predictable behavior on both platforms.

How Animated API works: Value, timing and spring

The foundation of Animated API is Animated.Value, a numeric value container initialized via the constructor new Animated.Value(0). Each Animated.Value stores an initial number and provides animate methods: timing, spring, and decay. The timing method creates linear or easing animation with duration, delay, and easing parameters. The spring method implements physical spring animation with friction, tension, and velocity parameters. The decay method creates animation with inertia and damping — useful for swipes and scrolling. All methods return an Animated.Composite object that can be started via start() and stopped via stop(). Animation runs in a separate thread: when useNativeDriver = true, calculations happen in the native UI thread, leaving the JavaScript thread free for event handling and logic.

Animated.timing: configuring duration and easing

Animated.timing is the basic animation method with controlled duration. It accepts configuration: toValue, duration (default 500ms), easing (Easing.linear by default), and delay. Easing functions from the Easing module allow non-linear acceleration: Easing.bezier, Easing.elastic, Easing.bounce. For uniform speed animation use Easing.linear, for natural acceleration use Easing.inOut. Important: Animated.timing guarantees the animation will finish exactly at toValue within the specified time, regardless of device load.

Animated.spring: physics-based animation

Animated.spring implements a spring animation model based on Hooke’s law. The friction parameter controls oscillation count: the higher the friction, the faster the stop. The tension parameter determines spring stiffness: high tension speeds up movement. The velocity parameter sets the initial speed for animation with inertia — critically important for animations following user gestures. Animated.spring has no fixed duration — animation completes when speed and amplitude reach threshold values.

Animated.View, Animated.Text and other components

Animated API provides four built-in animated components: Animated.View, Animated.Text, Animated.ScrollView, and Animated.Image. Each is a wrapper over the corresponding native component that supports passing Animated.Value to style properties. Animated.View is the most used component, accepting the same props as a regular View, but with support for animated values in style. Animated.Text is useful for animating text color or inter-letter spacing. Animated.ScrollView allows animating scrollTo and contentOffset. Animated.Image supports animated opacity and scale during image loading. If you need to animate another component, use Animated.createAnimatedComponent(MyComponent).

js
import React from 'react';
import { Animated, View, Button } from 'react-native';

const FadeInView = () => {
  const opacity = useRef(new Animated.Value(0)).current;

  const fadeIn = () => {
    Animated.timing(opacity, {
      toValue: 1,
      duration: 1000,
      useNativeDriver: true,
    }).start();
  };

  return (
    View
      Animated.View { style: [{ opacity }] }
      Button title="Fade In" onPress={fadeIn}
  );
};

Interpolation system: from numbers to color and transformations

Interpolation is a mechanism for converting an input numeric range of Animated.Value into output values of another type. The interpolate method accepts configuration with inputRange (array of input values) and outputRange (array of output values). OutputRange types: numbers (coordinates, opacity), strings (rotation angles with ‘deg’), hex colors (‘#ff0000’), transform objects. Interpolation supports easing and extrapolate — behavior outside the specified range (clamp, extend, identity). For example, during a drag gesture, you can map finger position from 0 to 200 into opacity from 1 to 0, creating a fade effect on swipe. The interpolation system allows creating complex multi-step animations: value 0-0.5-1.0 can map to yellow-orange-red.

js
const spinValue = new Animated.Value(0);

Animated.timing(spinValue, {
  toValue: 1,
  duration: 3000,
  easing: Easing.linear,
  useNativeDriver: true,
}).start();

const spin = spinValue.interpolate({
  inputRange: [0, 1],
  outputRange: ['0deg', '360deg'],
});

Animation composition: sequence and parallelism

Animated API supports three animation composition modes: Animated.sequence, Animated.parallel, and Animated.stagger. Animated.sequence runs animations one after another: each next starts after the previous completes. Animated.parallel runs all animations simultaneously with one shared completion callback. Animated.stagger runs animations with a delay between each start — useful for creating wave effects. Compositions can be nested: sequence of parallel groups or parallel of sequences. This allows creating complex chains: staggered element appearance animation, parallel slide-in with fade-in, then a sequence of bounce and shake.

js
Animated.sequence([
  Animated.timing(fadeAnim, {
    toValue: 1,
    duration: 500,
    useNativeDriver: true,
  }),
  Animated.parallel([
    Animated.timing(scaleAnim, {
      toValue: 1.1,
      duration: 200,
      useNativeDriver: true,
    }),
    Animated.spring(colorAnim, {
      toValue: 1,
      friction: 4,
      useNativeDriver: true,
    }),
  ]),
]).start();

useNativeDriver and animation performance

useNativeDriver is an animation configuration option that moves all animation logic from the JavaScript thread to the native UI thread. Without useNativeDriver, animations execute via the JavaScript bridge: each value change is sent to the native thread, causing delays when the JS thread is busy with async operations. With useNativeDriver = true, Animated.Value updates directly on the native side, leaving the JavaScript thread free for event handling, API requests, and React reconciliation. Limitation: useNativeDriver only supports non-layout properties — opacity, transform, backgroundColor (via PlatformColor). For layout properties (width, height, top, left), NativeAnimatedModule or LayoutAnimation is required. According to React Native 0.76, all animated properties are supported via native driver except layout-based ones. useNativeDriver mode is recommended for all animations where possible — it boosts FPS from 30-40 to a stable 60.

Gesture-driven animation: PanResponder and Gesture Handler

PanResponder is a built-in React Native gesture handling system that integrates well with Animated API. PanResponder provides onPanResponderMove and onPanResponderRelease callbacks where Animated.Value can be updated based on finger position. For more complex gestures — swipe, pinch, rotation — use the react-native-gesture-handler library, which works synchronously with animations and provides 60 FPS even with multi-finger gestures. Gesture Handler provides Animated.event — a method that directly binds a gesture to Animated.Value without manual callback handling. The combination of Gesture Handler + Animated API is the industry standard for interactive animations in React Native applications.

Animated.event: binding gestures to values

Animated.event is a method that binds a native event (e.g., gestureEvent) directly to Animated.Value. Unlike manual callback handling, Animated.event works synchronously in the native thread and does not require the JavaScript bridge for each frame. This provides smooth animation even during fast swipes. Animated.event accepts an array of mappings, where each element binds an event field to Animated.Value. Nested access is supported: Animated.event([{ nativeEvent: { translationX: xValue } }]).

Code examples with Animated API

Let’s look at three practical examples of using Animated API in React Native projects. The first example is a card appearance animation with opacity + translateY sequence. The second example is a button pulse animation using spring. The third example is an interactive drag element with PanResponder. All examples use useNativeDriver = true and follow React Native 0.76 best practices.

js
const CardWithAnimation = () => {
  const anim = useRef(new Animated.Value(0)).current;

  React.useEffect(() => {
    Animated.spring(anim, {
      toValue: 1,
      friction: 6,
      tension: 40,
      useNativeDriver: true,
    }).start();
  }, []);

  const translateY = anim.interpolate({
    inputRange: [0, 1],
    outputRange: [50, 0],
  });

  return (
    Animated.View {
      style: [{ opacity: anim, transform: [{ translateY }] }]
    }
  );
};

Pulse animation via spring

Spring animation creates a natural pulse effect using a physical spring model. Low friction (2-4) and high tension (100-150) settings produce soft oscillations that decay naturally. Use Animated.loop for infinite pulsing with a sequence cycle: scale → 1.2, scale → 1.0. Pulsing is used for loading indicators, notifications, and accent buttons.

Frequently Asked Questions

How is Animated API different from LayoutAnimation?

Animated API provides full control over animation — duration, easing, interpolation, composition. LayoutAnimation is a built-in React Native system for animating layout changes with automatic interpolation. Animated API requires explicit declaration of Animated.Value and configuration, but allows creating complex chains. LayoutAnimation fires automatically on state changes and is simpler to use, but limited in flexibility.

Can width and height be animated via Animated API?

Yes, width and height can be animated via Animated API, but they do not support useNativeDriver. Layout property animation requires the JavaScript driver, as the native driver only works with non-layout properties. Use Animated.Value with toValue for width/height and set useNativeDriver to false. For better layout animation performance, consider LayoutAnimation or react-native-reanimated.

How to stop a running animation in Animated API?

Call the stop() method on the animation object returned by Animated.timing or Animated.spring. Example: animRef.stop(). If the animation is part of a sequence or parallel, stop() stops the entire group. To check status, use the callback in start(callback) — it receives a result object with finished: false on forced stop.

What is Animated.ValueXY and when to use it?

Animated.ValueXY is a container for two-dimensional coordinates, storing two Animated.Value: x and y. Use it for animating element position on screen — drag, pan, swipe. ValueXY provides ready-made getLayout() for styles and getTranslateTransform() for transformations. This is convenient when working with PanResponder where both axes need to be animated simultaneously.

How to measure animation FPS in React Native?

Use the React Native Performance Monitor, built into the dev menu (Cmd+D / Cmd+M). Enable FPS Monitor — it shows UI FPS and JS FPS in real time. For programmatic measurement, use import { InteractionManager } to track animation completion. Stable 60 UI FPS and 50+ JS FPS indicate a well-optimized animation. If UI FPS drops below 30, disable useNativeDriver or optimize the number of concurrent animations.

Summary

  • Animated API — a declarative React Native animation library with native driver support for 60 FPS
  • Animated.Value — a basic numeric value container that subscribes components to changes without re-render
  • Timing, Spring, Decay — three animation modes: time-controlled, physical spring, and inertial
  • Interpolation converts numeric ranges into colors, angles, coordinates — the basis for complex visual effects
  • Composition via sequence, parallel, and stagger enables multi-step animation chains
  • useNativeDriver is essential for performance — moves computations to the native UI thread
  • PanResponder and Gesture Handler integrate with Animated API for interactive gesture animations
  • Use Animated.event for direct gesture-to-value binding without the JavaScript bridge

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also