React Native 0.87 fait de la Strict TypeScript API le défaut. Voici l'ordre de mise à jour.
React Native 0.87 est sorti le 11 août, et c'est la version avec le plus de ruptures de compatibilité que le framework ait connue depuis longtemps. Le point central : la Strict TypeScript API, disponible en preview optionnelle depuis la 0.80, est désormais activée par défaut pour tous les projets. À ses côtés : le support expérimental de Swift Package Manager sur iOS, la prise en charge d'Android Gradle Plugin 9 en première classe, et un plancher d'outillage plus élevé. Node.js 22.13+, Kotlin 2.0+ avec la version 2.2 embarquée, et compileSdk passé à 37.
Si votre application est encore sur une version plus ancienne, il ne s'agit pas d'une mise à jour de version routinière. L'équipe React Native la qualifie de la plus grande avancée vers la 1.0 depuis longtemps, et la liste des suppressions le confirme.
Ce que la Strict API change concrètement
Jusqu'à présent, les types TypeScript de React Native étaient maintenus manuellement, séparément du code source, ce qui entraînait des dérives. Les types promettaient des choses que le code ne faisait pas, et des chemins de fichiers internes se retrouvaient exposés comme s'ils étaient publics. La Strict API corrige cela en générant les types directement depuis le code source et en limitant le contrat public à ce que react-native exporte à sa racine.
La conséquence pratique : les imports profonds comme react-native/Libraries/... sont désormais des erreurs de type. Si vous avez déjà accédé à un chemin interne pour récupérer quelque chose qui n'était pas officiellement exporté, ce code ne passera plus le contrôle de types. Les types de ref changent également. Les composants natifs sont maintenant typés comme des fonctions, et non plus comme des classes, donc useRef<View>() ne fonctionne plus. Chaque composant obtient à la place un type d'instance dédié, comme ViewInstance et TextInputInstance.
Il existe une échappatoire temporaire. Vous pouvez revenir aux anciens types manuels avec customConditions: ["react-native-legacy-deep-imports"] dans votre tsconfig.json. Considérez cela comme un espace de respiration, pas une destination. L'équipe a indiqué que cette option de retour disparaîtra dans une prochaine version, donc la migration est inévitable, que vous la fassiez maintenant ou plus tard.
Un détail qui vous évitera une mauvaise après-midi : la Strict API n'affecte que l'analyse TypeScript de votre propre projet, délimitée par votre tsconfig.json, et repose sur l'activation de skipLibCheck. La configuration TypeScript de React Native l'active par défaut. Si vous avez désactivé skipLibCheck, réactivez-le avant de commencer, sinon vous serez submergé d'erreurs provenant de fichiers .d.ts tiers que vous ne pouvez pas corriger.
Les suppressions qui pénalisent les applications matures
La Strict API fait les gros titres, mais ce sont les suppressions discrètes qui cassent les bases de code plus anciennes. Voici quelques-unes sur lesquelles nous ferions un grep en premier :
InteractionManagera été supprimé. Déplacez les travaux différés versrequestIdleCallback.- Les TurboModules sont désormais toujours activés. Le feature flag
useTurboModulesest supprimé ; si vous le commutez encore, ce code doit disparaître. useColorScheme()retourneColorSchemeName | nullet ne retourne plus'unspecified'. Toute branche gérant cette chaîne est désormais morte.- Les props
StatusBardépréciées (backgroundColor,translucent) et leurs setters sont supprimés, ainsi que la propanimateddeModalet le support booléen dekeyboardShouldPersistTapsdansScrollView.
Aucune de ces suppressions n'est difficile en soi. Le problème est de les trouver toutes dans une grande application avant qu'elles ne surgissent à l'exécution ou dans un CI en échec.
SwiftPM et AGP 9 : réel, mais pas urgent
Les modifications côté natif sont celles qui nous intéressent le plus dans notre travail mobile. Le support de Swift Package Manager signifie que vous pouvez enfin construire un projet iOS sans Ruby, Bundler ou CocoaPods dans la boucle. C'est expérimental et optionnel, CocoaPods reste le chemin par défaut et supporté, et il consomme les mêmes XCFrameworks préconstruits que React Native embarque déjà. Dans nos projets iOS natifs, la chaîne d'outils CocoaPods a été une source fiable d'échecs CI « ça marche sur ma machine », donc un chemin qui n'utilise que Xcode est vraiment le bienvenu. Nous ne migrerions pas encore un build de production dessus, mais ça vaut la peine de le tester sur une branche pour voir comment il gère votre graphe de dépendances.
Sur Android, la 0.87 est la première version à prendre en charge AGP 9. La recommandation officielle de l'équipe est révélatrice : désactivez pour l'instant le Kotlin intégré d'AGP 9 et le nouveau DSL en définissant android.builtInKotlin=false et android.newDsl=false dans gradle.properties. Ces options de désactivation sont censées disparaître autour d'AGP 10. En d'autres termes, Google et l'équipe React Native sont encore en train de stabiliser cela, et le chemin recommandé est délibérément conservateur. De notre expérience avec Kotlin et Jetpack Compose, nous avons appris à respecter ce type de recommandations. Adopter un plugin Gradle majeur la semaine de son lancement, avec les valeurs par défaut que les mainteneurs vous disent eux-mêmes de désactiver, c'est ainsi que vous perdez un sprint à cause d'erreurs de build.
L'ordre de mise à jour que nous utiliserions
Voici la séquence que nous suivrions pour une vraie application, en commençant par le risque le plus faible :
- Mettez à jour votre chaîne d'outils avant de toucher à React Native. Passez à Node.js 22.13+, Kotlin 2.0+ et compileSdk 37 en étapes séparées et vérifiables. Si quelque chose casse ici, vous voulez savoir que c'était la chaîne d'outils, pas le framework.
- Mettez à jour vers la 0.87 avec l'option de retour aux types legacy encore activée. Cela isole les suppressions à l'exécution — les changements d'
InteractionManageret deStatusBar— de la migration des types, afin de déboguer une chose à la fois. - Activez la Strict API en dernier. Retirez l'option de retour, exécutez
tsc, et traitez les erreurs d'imports profonds et de types de ref dans une passe dédiée. C'est le changement le plus susceptible de toucher le code partagé et les bibliothèques tierces, donc donnez-lui son propre PR.
La partie actionnable que vous pouvez faire dès aujourd'hui, avant toute mise à jour : lancez une recherche à l'échelle du projet pour react-native/Libraries/ et chaque import profond dans les internals de React Native. Ce seul grep vous indique l'ampleur réelle du travail lié à la Strict API. Si le compteur est à zéro, cette mise à jour est principalement mécanique. S'il est dans les centaines, vous avez une conversation de planification, pas une mise à jour du vendredi après-midi.
Il y a une leçon plus large que nous constatons dans le web et le mobile. Quand nous construisons des applications cloud-native pour des clients en entreprise, les frameworks qui survivent sont ceux qui finissent par tracer une frontière nette autour de leur API publique et s'y tiennent. React Native a dérivé pendant des années parce que les types et le code source étaient deux choses différentes maintenues manuellement. Cette version est la correction. Ça fait mal une fois, puis les refactorisations internes cessent d'être vos breaking changes. C'est un compromis qui en vaut la peine, et les équipes en entreprise suisses avec lesquelles nous travaillons, où un breaking change imprévu peut bloquer la validation de conformité, choisiront une API prévisible plutôt qu'une pratique à chaque fois. Vous pouvez voir le type de travail mobile et de développement que nous faisons sur des projets natifs et cross-platform.
Si un audit « lesquels de nos imports vont devenir des erreurs de type » vous semble familier, parlons-en. Nous aidons les équipes à planifier des mises à jour de framework qui ne se transforment pas en corvées de plusieurs mois.