Skip to content

iOS Fabric: useAnimatedProps({ color }) on <Svg> doesn't repaint per frame — only final value lands #2962

Description

@pranko17

Description

On iOS Fabric (new architecture), animating the color prop of <Svg> via Reanimated's useAnimatedProps doesn't visually update per frame. The icon stays at the initial color for the full duration of the timing animation, then snaps to the final color.

The same SharedValue consumed by useAnimatedStyle on a sibling <Animated.Text> animates smoothly, so Reanimated's per-frame worklet path is firing — the SVG view just doesn't redraw on the synchronous prop updates.

The issue does not occur on Android — both icon and label animate smoothly there.

Steps to reproduce

  1. Render an Animated.createAnimatedComponent(Icon) alongside an Animated.Text, both driven by the same SharedValue<string> produced by withTiming on a hex color string.
  2. On Svg, color goes through useAnimatedProps; on Text, through useAnimatedStyle.
  3. Toggle the source state — observe that the text smoothly transitions, the icon doesn't.

Consumer:

const animatedColor = useDerivedValue(() => {
  return withTiming(color, {
    duration: 150,
    easing: Easing.inOut(Easing.ease),
  });
}, [color]);

const animatedProps = useAnimatedProps(() => {
  return { color: animatedColor.get() };
}, [animatedColor]);

const labelAnimatedStyle = useAnimatedStyle(() => {
  return { color: animatedColor.get() };
}, [animatedColor]);

return (
  <Pressable style={styles.root} onPress={handlePress}>
    <Icon animatedProps={animatedProps} height={24} width={24} />
    <AnimatedText style={[styles.label, labelAnimatedStyle]}>{label}</AnimatedText>
  </Pressable>
);

Where Icon is Animated.createAnimatedComponent(IconExample) and IconExample is a plain SVG using the currentColor cascade:

import { type FC } from 'react';
import Svg, { Path, type SvgProps } from 'react-native-svg';

const IconExample: FC<SvgProps> = ({ color, height = 24, width = 24, ...props }) => {
  return (
    <Svg color={color} fill="none" height={height} viewBox="0 0 24 24" width={width} {...props}>
      <Path
        d="M9 16A7 7 0 1 0 9 2a7 7 0 0 0 0 14Z"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth={2}
      />
      <Path
        d="M15 22a7 7 0 1 0 0-14 7 7 0 0 0 0 14Z"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth={2}
      />
    </Svg>
  );
};

export default IconExample;

Video

Screen.Recording.2026-05-15.at.21.49.56.mov

Tapping between tab bar items — the label color smoothly interpolates while the icon stroke jumps only at the end of each 150ms window.

Snack or a link to a repository

Will follow up with a minimal repro repository shortly.

SVG version

15.15.5

React Native version

0.85.3

Platforms

iOS

JavaScript runtime

Hermes

Workflow

React Native (without Expo)

Architecture

Fabric (New Architecture)

Build type

Debug app & dev bundle

Device

Real device

Device model

iPhone (reproduces on simulator as well)

Acknowledgements

Yes

Metadata

Metadata

Assignees

No one assigned

    Labels

    Missing reproThis issue need minimum repro scenario

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions