React Native Reanimated 4 : Guide Complet des Animations Fluides (2026)
Guide pratique de React Native Reanimated 4 : nouvelle API CSS, animations de layout, worklets, migration depuis Reanimated 3 et compatibilité New Architecture. Installation Expo, exemples de code et dépannage FPS.
React Native Reanimated 4 est la refonte majeure de la bibliothèque d'animations la plus utilisée de l'écosystème React Native. Elle apporte une API de style CSS, des animations de layout natives, un support complet de la New Architecture et un moteur de worklets recompilé qui exécute 100% des animations sur le thread UI. Concrètement, si vous démarrez un projet en 2026, Reanimated 4 est le choix par défaut pour toute animation dépassant la simple opacité. Et honnêtement, cette version rend enfin obsolète la gymnastique de useNativeDriver qui empoisonnait l'Animated API historique (j'ai perdu tellement d'heures là-dessus sur mon dernier projet e-commerce).
Reanimated 4 stable est sorti en août 2025 et exige React Native 0.75+ et la New Architecture activée pour toutes les nouveautés (les animations CSS, notamment).
La nouvelle API animations imite la syntaxe CSS (transitionProperty, animationName, @keyframes) et remplace la plupart des useAnimatedStyle pour les cas simples.
Les worklets fonctionnent désormais avec Worklets 0.6+, un package séparé qui améliore la compilation Babel et supprime les erreurs "worklet not found".
Les animations de layout (LinearTransition, FadeIn, SlideInRight) sont stables et remplacent LayoutAnimation d'origine.
La migration depuis Reanimated 3 est majoritairement automatique via npx react-native-reanimated@4 upgrade, avec quelques ruptures sur useAnimatedGestureHandler (supprimé).
Le combo Reanimated 4 + Gesture Handler 2.20+ + Expo SDK 53+ est l'unique combinaison testée pour la production en 2026.
Quelles sont les nouveautés de Reanimated 4 ?
Reanimated 4 introduit quatre changements majeurs par rapport à la version 3. D'abord, une API d'animation inspirée de CSS : vous écrivez animationName, animationDuration et @keyframes presque comme sur le web, ce qui supprime le besoin d'un useAnimatedStyle pour 60 % des cas d'usage courants (fade-in, pulsations, transitions de couleur). Deuxièmement, Worklets a été extrait dans un package séparé (react-native-worklets), ce qui règle enfin les erreurs de plugin Babel qui rendaient l'onboarding pénible.
Troisièmement, les animations de layout sont stables. LinearTransition, FadeIn, SlideInRight, ZoomOut etc. fonctionnent sur toute vue Animated.View sans configuration supplémentaire, y compris à l'intérieur de listes FlatList. Quatrièmement, la compatibilité New Architecture est totale : Fabric, TurboModules et Bridgeless mode sont supportés, avec des gains de performance mesurés à 15–20 % sur les animations complexes selon les benchmarks officiels Software Mansion. Enfin, plusieurs API historiques ont été supprimées : useAnimatedGestureHandler, l'ancien createAnimatedComponent non-typé et les callbacks runOnJS non-worklet.
Comment installer Reanimated 4 dans un projet Expo
L'installation de Reanimated 4 diffère selon que vous utilisez Expo (managed) ou React Native bare. Bonne nouvelle : pour un projet Expo SDK 53+, une seule commande suffit.
Expo installe automatiquement les versions compatibles (Reanimated 4.x, Worklets 0.6.x, Gesture Handler 2.20+). Ensuite, ajoutez le plugin Babel dans babel.config.js. C'est l'étape que la moitié des issues GitHub oublie :
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [
// 'react-native-worklets/plugin' DOIT être en dernier
'react-native-worklets/plugin',
],
};
};
Pour un projet bare React Native 0.75+, ajoutez également l'entrée pod install après l'installation npm, puis reconstruisez : cd ios && pod install && cd .. && npx react-native run-ios. Sur Android, aucune configuration Gradle supplémentaire n'est requise depuis Reanimated 3.5.
Concepts fondamentaux : worklets et shared values
Un worklet est une petite fonction JavaScript exécutée sur le thread UI plutôt que sur le thread JS. C'est ce qui permet à Reanimated d'atteindre 60 ou 120 FPS même quand le thread JS est bloqué par un fetch réseau ou un re-render lourd. Vous les créez en préfixant une fonction avec 'worklet' ou en les passant à des hooks comme useAnimatedStyle, useDerivedValue ou useAnimatedReaction.
Une shared value, elle, est une référence mutable synchronisée entre le thread JS et le thread UI. Vous la lisez et l'écrivez via .value, et toute modification déclenche automatiquement la ré-évaluation des worklets qui en dépendent. Voici l'exemple canonique d'une boîte qui grossit au tap :
Les fonctions withSpring, withTiming et withDecay sont les trois primitives d'interpolation. withSpring reste la plus utilisée, car sa physique (mass, damping, stiffness) donne un rendu naturel sans devoir régler manuellement une courbe de Bézier.
La nouvelle API d'animations style CSS
La grande révolution de Reanimated 4 est la CSS Animations API. Pour les animations simples, vous n'avez plus besoin de useSharedValue ni de useAnimatedStyle. Vous déclarez l'animation directement dans le style, comme sur le web :
La liste des propriétés supportées inclut animationName, animationDuration, animationDelay, animationIterationCount, animationDirection, animationTimingFunction, animationFillMode, ainsi que leurs équivalents transitionProperty, transitionDuration et transitionTimingFunction. Vous pouvez également passer un tableau à animationName pour définir plusieurs keyframes.
Cette API est particulièrement pratique pour les micro-interactions et les états loading/skeleton. Elle évite la sur-utilisation des hooks React pour des choses qui, sur le web, seraient trois lignes de CSS. Attention cependant : la CSS Animations API nécessite la New Architecture activée. En mode legacy, le style est simplement ignoré et l'animation ne joue pas. J'ai perdu une demi-journée là-dessus, avant de comprendre que mon dev client n'avait pas Fabric activé.
Animations de layout et transitions d'entrée/sortie
Les animations de layout jouent automatiquement quand une vue apparaît, disparaît ou change de position dans son parent. Elles remplacent avantageusement l'ancien LayoutAnimation de React Native qui souffrait de nombreux bugs sur Android. Trois catégories :
Entering : FadeIn, SlideInRight, ZoomIn, BounceIn, FlipInEasyX, etc.
Toutes les animations de layout supportent le chaînage : .duration(400).delay(100).springify().damping(15). Si vous les combinez avec une liste performante comme FlashList v2 pour les listes React Native, évitez LinearTransition pour les items, parce que le recyclage du composant provoque des animations parasites. Utilisez plutôt entering/exiting seuls.
Animations pilotées par les gestes
Reanimated 4 fonctionne main dans la main avec React Native Gesture Handler 2.20+. L'API useAnimatedGestureHandler historique a été supprimée et remplacée par le nouveau Gesture déclaratif de Gesture Handler, plus lisible et compatible avec les worklets modernes. Voici un composant swipeable :
runOnJS est indispensable pour appeler du code JS (comme un callback React) depuis un worklet. Sans lui, l'appel serait exécuté sur le thread UI et provoquerait un crash silencieux. En complément, si vous shippez des animations complexes en production, activez le mode strict via configureReanimatedLogger({ strict: true }) pour voir immédiatement les worklets mal formés dans les nouveaux React Native DevTools.
Migration de Reanimated 3 vers 4
Le processus de migration est majoritairement automatique. Pour un projet existant en Reanimated 3.x :
Bumpez React Native à 0.75 minimum et activez la New Architecture dans app.json (newArchEnabled: true) ou gradle.properties.
Remplacez 'react-native-reanimated/plugin' par 'react-native-worklets/plugin' dans babel.config.js.
Exécutez le codemod : npx react-native-reanimated@4 upgrade. Il réécrit automatiquement useAnimatedGestureHandler en Gesture.Pan().
Cherchez les usages de createAnimatedComponent sans type et ajoutez le type générique : Animated.createAnimatedComponent<MyProps>(MyComp).
Testez sur iOS et Android. Les bugs de layout animations dans des FlatList sont la principale régression rencontrée.
Le codemod ne gère pas les cas où useAnimatedGestureHandler est utilisé avec des types custom ou wrappé dans un HOC. Dans ce cas, réécrivez manuellement en suivant le guide de migration officiel Gesture Handler. Comptez une demi-journée pour un projet moyen (~30 composants animés). Sur mon dernier projet, la migration a pris à peu près deux heures sur 22 composants, plus une heure de correctif pour un bug de SharedValue mal typé.
Pourquoi mon animation Reanimated saccade ?
Le principal atout de Reanimated est que les animations s'exécutent sur le thread UI, donc théoriquement sans jank. Si vous observez du saccadement, sept causes couvrent 95 % des cas :
Vous animez une propriété non-native.width, height, borderRadius passent par le thread JS sur l'ancienne architecture. Préférez scale et translate.
Vous mettez à jour .value depuis le thread JS dans une boucle React. Chaque update coûte un pont ; regroupez ou utilisez useDerivedValue.
Vous n'avez pas activé Hermes. Reanimated fonctionne sans, mais les worklets sont sensiblement plus lents sur JSC.
Vous relancez withSpring en boucle dans un useEffect. Chaque call crée une nouvelle animation qui écrase la précédente, et la valeur "saute".
Votre composant re-render à 60 Hz. Un state React qui change à chaque frame casse la mémoïsation ; ancrez tout dans les shared values.
Vous testez sur simulateur. Les animations paraissent saccadées sur simulateur iOS et émulateur Android. Mesurez toujours sur appareil physique.
Vous mesurez sans le mode Release. Le dev mode ajoute des overheads massifs ; profilez toujours en --configuration Release ou eas build --profile production.
Pour diagnostiquer, activez le Performance Monitor intégré (Cmd+D puis "Show Perf Monitor") et vérifiez que le thread UI reste à 60 FPS (ou 120 sur iPhone Pro). Si le thread JS chute mais que UI reste stable, c'est bon signe : votre animation est bien sur le thread UI. Combinez avec l'article optimiser le démarrage React Native pour un profil complet.
Reanimated 4 et la New Architecture
Reanimated 4 est obligatoirement compatible avec la New Architecture pour bénéficier de toutes les fonctionnalités (CSS animations, animations de layout stables, Fabric renderer). En mode legacy, la bibliothèque fonctionne toujours mais désactive silencieusement les nouveautés, ce qui explique pourquoi certains développeurs ne voient pas l'API CSS s'appliquer.
Pour activer la New Architecture dans un projet Expo :
Puis reconstruisez avec eas build --profile development --clear-cache. Sur bare React Native, ajoutez newArchEnabled=true à android/gradle.properties et exécutez RCT_NEW_ARCH_ENABLED=1 pod install. Les principaux gains observables : (a) suppression totale du décalage entre les animations JS et natives dans les scrollviews, (b) rendu synchrone de onLayout qui rend les animations de layout beaucoup plus fluides, (c) meilleure gestion mémoire dans les listes animées.
Pour une compréhension complète des enjeux, consultez notre guide de migration vers la New Architecture. À noter : quelques bibliothèques tierces (notamment react-native-svg avant la version 15.5) ont des problèmes connus avec Fabric et Reanimated 4. Consultez le changelog GitHub Reanimated avant chaque bump majeur pour vérifier les breaking changes récents.
Questions fréquentes
Reanimated 4 est-il compatible avec Expo Go ?
Oui, Reanimated 4 est inclus dans Expo Go depuis SDK 53. Cependant, la CSS Animations API et certaines animations de layout nécessitent la New Architecture activée, ce qui n'est possible qu'avec un development build, pas dans le client Expo Go public. Pour tester ces fonctionnalités, générez un dev client avec npx expo run:ios ou eas build --profile development.
Quelle est la différence entre Reanimated et React Native Animated ?
Animated (la bibliothèque native de React Native) exécute la logique sur le thread JS et copie les valeurs via le pont, ce qui cause du jank dès que JS est occupé. Reanimated exécute tout sur le thread UI via des worklets, garantissant 60/120 FPS même en cas de blocage JS. Pour tout projet récent, Reanimated est le choix par défaut.
Peut-on utiliser Reanimated 4 sans Gesture Handler ?
Oui, absolument. Reanimated peut animer n'importe quel Animated.View sans dépendre de Gesture Handler. Vous n'en avez besoin que pour des animations pilotées par des gestes (pan, pinch, long-press). Pour des animations pilotées par le temps ou l'état React, seul react-native-reanimated et react-native-worklets suffisent.
Comment déboguer un worklet qui plante silencieusement ?
Activez configureReanimatedLogger({ strict: true, level: 'warn' }) au démarrage de l'app. Utilisez console.log à l'intérieur du worklet, les logs s'affichent dans les React Native DevTools. Pour les stack traces exploitables, désactivez la minification en dev : metro.config.js puis transformer: { minifierConfig: { keep_fnames: true } }.
Reanimated fonctionne-t-il avec React Native Web ?
Partiellement. Reanimated 4 fournit un fallback web basé sur les CSS transitions et animations, ce qui couvre la majorité des cas simples. Les animations de layout et les gestures avancées ont un support limité. Testez toujours sur web avant de déployer une PWA : la parité n'est pas garantie à 100 %.
Réduisez le cold start React Native de 59 % en 2026 : Hermes bytecode, inlineRequires, splash natif et défer des SDK tiers. Mesures Perfetto et code inclus.
FlatList, FlashList v2 ou LegendList : quel composant de liste choisir en React Native en 2026 ? Comparatif avec benchmarks, code concret et guide de migration.