Skip to content

rn-prefer-reanimated: native-driver opacity animation reported as JS-thread animation #1784

Description

@thomasorgeval

The rule reports the Animated import as a JS-thread animation even though the only animation explicitly uses useNativeDriver: true and only animates opacity.

Reproduction

Reproduced with React Doctor 0.9.13, Node 24.18.0, on macOS. JSON report: schemaVersion: 3, ok: true, project complete: true. This is a static-analysis reproduction; no runtime jank is inferred from the warning.

Create a directory with this package.json, add the file below, and run:

npx --yes react-doctor@0.9.13 . --scope full --json --blocking none --yes --no-score
{"name":"react-doctor-rule-repros","private":true,"version":"1.0.0","dependencies":{"react":"19.2.7","react-native":"0.86.2","@shopify/flash-list":"2.3.2","@tanstack/react-query":"5.101.0","zustand":"5.0.14"}}

NativePulse.tsx:

import { useEffect, useState } from 'react';
import { Animated } from 'react-native';

export function NativePulse() {
  const [opacity] = useState(() => new Animated.Value(1));
  useEffect(() => {
    const animation = Animated.loop(
      Animated.timing(opacity, {
        toValue: 0.7,
        duration: 2000,
        useNativeDriver: true,
        isInteraction: false,
      }),
    );
    animation.start();
    return () => animation.stop();
  }, [opacity]);
  return <Animated.View style={{ opacity }} />;
}

Actual

“Your users see stutter when Animated from react-native runs on the JS thread.”

The suggested fix is to switch to Reanimated. The example already delegates animation frames to the native driver, so the diagnostic does not establish the claimed JS-frame work or a reason to migrate.

Expected

Avoid classifying a proven native-driver timing animation as JS-driven. If this remains an import-level heuristic, word the diagnostic as a conditional investigation rather than a runtime defect. A regression test should distinguish this example from useNativeDriver: false; the presence of one native-driver call should not exempt unrelated JS-driven animations in the same file.

Notes

The current rule inspects Animated / LayoutAnimation imports without inspecting animation configuration. These APIs also need separate migration guidance. React Native Animated: using the native driver.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions