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.
The rule reports the
Animatedimport as a JS-thread animation even though the only animation explicitly usesuseNativeDriver: trueand only animates opacity.Reproduction
Reproduced with React Doctor 0.9.13, Node 24.18.0, on macOS. JSON report:
schemaVersion: 3,ok: true, projectcomplete: 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: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/LayoutAnimationimports without inspecting animation configuration. These APIs also need separate migration guidance. React Native Animated: using the native driver.