Pour passer une application Capacitor à Capacitor 8, installez Node.js 22+, Xcode 26+ et Android Studio Otter, puis mettez à jour @capacitor/cli vers la dernière version 8.x, puis exécutez bunx cap migrate, puis corrigez ce que le migrateur signale. Les principaux breaking changes sont iOS 15 comme cible de déploiement minimale, Android SDK 36 avec minSdk 24, AGP 8.13 avec Gradle 8.14.3, et la suppression de adjustMarginsForEdgeToEdge au profit du nouveau plugin System Bars.
Ce guide détaille le parcours automatisé, chaque étape manuelle associée et les erreurs les plus fréquentes après la mise à niveau. Si vous maintenez un plugin plutôt qu'une application, lisez Comment mettre à niveau votre plugin Capacitor vers Capacitor 8 plutôt.
Les prérequis de Capacitor 8 en un coup d'œil
Vérifiez votre toolchain avant de toucher au projet. La plupart des échecs de mise à niveau viennent d'un vieux JDK, d'un vieux Xcode ou d'un vieux Node en CI, pas du code.
| Domaine | Capacitor 7 | Capacitor 8 |
|---|---|---|
| Node.js | 20+ | 22+ (le CLI déclare engines.node >= 22.0.0) |
| Xcode | 16+ | 26+ |
| Cible de déploiement iOS | 14.0 | 15.0 |
| Android Studio | Ladybug | Otter 2025.2.1+ |
| minSdkVersion | 23 | 24 |
| compileSdkVersion / targetSdkVersion | 35 | 36 |
| Android Gradle Plugin | 8.7.2 | 8.13.0 |
| Gradle wrapper | 8.11.1 | 8.14.3 |
| Kotlin (si utilisé) | 1.9.25 | 2.2.20 |
| JDK pour les builds Android | 21 | 21 (@capacitor/android compile avec Java 21) |
| Nouvelle plateforme iOS par défaut | CocoaPods | Swift Package Manager |
Xcode 26 n’est pas seulement une exigence Capacitor. Depuis le 28 avril 2026, App Store Connect rejette les uploads compilés avec une version antérieure d’Xcode, il vous en faut donc de toute façon. Voir Xcode 26 désormais exigé par Apple pour les apps Capacitor pour les détails.
Avant de commencer
- Committez tout, ou créez une branche. Le migrateur modifie les fichiers natifs en place.
- Assurez-vous que l’app se compile sur Capacitor 7 aujourd’hui. Mettre à niveau un projet cassé n’ajoute que du bruit.
- If you are on Capacitor 6 or older, do the previous major first. Each major has its own migration logic in the CLI.
- Listez vos plugins avec
bunx cap lset vérifiez que chacun a une release compatible avec Capacitor 8. Consultez lepeerDependenciesde la dernière version :
bun pm view @capgo/capacitor-updater peerDependencies
Un plugin avec @capacitor/core: ^7.0.0 comme peer s’installera avec des avertissements et peut échouer à la compilation. Les plugins Capgo suivent la version majeure de Capacitor dans leur propre numéro de version, donc @capgo/* les releases 8.x ciblent Capacitor 8.
- Mettez à jour les toolchains locales et CI : Node 22, Xcode 26, JDK 21, Android Studio Otter. Dans les GitHub Actions, épinglez une image macOS qui inclut Xcode 26 et utilisez
actions/setup-javaparjava-version: '21'.
Option 1 : mettre à niveau avec cap migrate
Le CLI fournit une commande de migration qui prend en charge la majeure partie du travail. Installez la dernière version du CLI, puis exécutez-la :
bun add -D @capacitor/cli@latest
bunx cap migrate
Le migrateur vous demande s'il doit installer les nouveaux paquets Capacitor et vous laisse choisir entre npm, Yarn, pnpm ou Bun. Choisissez Bun si votre projet contient un bun.lock. Vous pouvez ignorer le prompt avec bunx cap migrate --noprompt.
Ce qui change pour vous :
- Bumps
@capacitor/core,@capacitor/ios,@capacitor/androidet des plugins officiels@capacitor/*plugins en 8.x. - Définit
IPHONEOS_DEPLOYMENT_TARGET = 15.0dans le projet Xcode etplatform :ios, '15.0'dans le Podfile. - Mises à jour
variables.gradle, le classpath AGP, le wrapper Gradle etkotlin_version. - Ajouts
densityversandroid:configChangesdansAndroidManifest.xml.
Lisez la sortie complète. Si une étape ne peut pas être appliquée, par exemple parce qu'un fichier a été personnalisé, le CLI affiche une erreur avec le nom du fichier et continue. Ces lignes forment votre liste de tâches manuelles.
Une fois terminé :
bun run build
bunx cap sync
Ouvrez ensuite chaque plateforme et compilez-l’une fois depuis l'IDE pour voir les erreurs natives en entier.
Option 2 : mettre à jour manuellement
Si vos projets natifs sont fortement personnalisés ou si le migrateur a omis certaines étapes, appliquez les modifications manuellement. Elles correspondent aux guide officiel de mise à niveau Capacitor 8.
Mettez à jour les paquets npm
bun add @capacitor/core@latest @capacitor/ios@latest @capacitor/android@latest
bun add -D @capacitor/cli@latest
Mettez ensuite à jour chaque plugin officiel, par exemple :
bun add @capacitor/app@latest @capacitor/splash-screen@latest @capacitor/status-bar@latest
iOS : relevez la cible de déploiement à 15.0
Dans Xcode, sélectionnez le projet, ouvrez Paramètres de build, trouvez Cible de déploiement iOS sous Déploiement et réglez-le sur 15,0. Répétez l’opération pour chaque cible d’application, y compris les extensions.
Si l’application utilise encore CocoaPods, mettez à jour ios/App/Podfile:
platform :ios, '15.0'
Puis exécutez bunx cap sync ios, qui exécute pod install pour vous.
Si l’application utilise SPM, le CLI se régénère ios/App/CapApp-SPM/Package.swift à chaque synchronisation avec la bonne version de la plateforme et une version exacte capacitor-swift-pm qui correspond à celle installée @capacitor/ios. Ne modifiez pas ce fichier manuellement.
iOS : supprimer les notifications de view controller personnalisées
Capacitor 8 émet désormais CAPBridgeViewController notifications pour viewDidAppear et viewWillTransition lui-même. Si vous avez ajouté une extension ou une sous-classe pour publier .capacitorViewDidAppear ou .capacitorViewWillTransition, supprimez-la, sinon les listeners se déclencheront deux fois.
Android : mettez à jour Android Studio et l'AGP
Installez Android Studio Otter ou une version plus récente, ouvrez le android dossier et exécutez Outils > Assistant de mise à niveau AGP. Choisissez 8.13.0 et exécutez les étapes sélectionnées. Ou modifiez android/build.gradle directement :
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:8.13.0'
classpath 'com.google.gms:google-services:4.4.4'
}
}
Et android/gradle/wrapper/gradle-wrapper.properties:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip
Android : mise à jour variables.gradle
ext {
minSdkVersion = 24
compileSdkVersion = 36
targetSdkVersion = 36
androidxActivityVersion = '1.11.0'
androidxAppCompatVersion = '1.7.1'
androidxCoordinatorLayoutVersion = '1.3.0'
androidxCoreVersion = '1.17.0'
androidxFragmentVersion = '1.8.9'
coreSplashScreenVersion = '1.2.0'
androidxWebkitVersion = '1.14.0'
junitVersion = '4.13.2'
androidxJunitVersion = '1.3.0'
androidxEspressoCoreVersion = '3.7.0'
cordovaAndroidVersion = '14.0.1'
}
Conservez les variables supplémentaires lues par vos plugins (par exemple firebaseMessagingVersion). Les mises à jour des plugins officiels pour Capacitor 8 incluent firebaseMessagingVersion = '25.0.1', androidxBrowserVersion = '1.9.0', androidxMaterialVersion = '1.13.0' et androidxExifInterfaceVersion = '1.4.1'.
Android : passez à = l'assignation dans les fichiers Gradle
Gradle a déprécié la syntaxe d’attribution avec espace. Elle n’émet qu’un avertissement pour l’instant, mais elle cassera dans une future release Gradle, donc corrigez-la maintenant dans android/app/build.gradle:
android {
- namespace "com.example.app"
- compileSdk rootProject.ext.compileSdkVersion
+ namespace = "com.example.app"
+ compileSdk = rootProject.ext.compileSdkVersion
defaultConfig {
aaptOptions {
- ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
+ ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
}
}
}
Les appels de méthode tels que google() ou mavenCentral() restent inchangés.
Android : Kotlin et configChanges
If your app module uses Kotlin, set kotlin_version = '2.2.20'. Kotlin 2.x transforme l’ancien kotlinOptions {} bloc en une erreur, déplacez donc jvmTarget en kotlin { compilerOptions { ... } }.
Ajoutez ensuite density à l’activité principale pour que le WebView ne soit pas recréé lors d’un changement de densité d’affichage (appareils pliables, redimensionnement de la fenêtre, réglages de taille d’écran) :
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode|navigation|density"
Android : la disposition du bridge a été renommée
bridge_layout_main.xml n’existe plus. Si votre MainActivity ou un fragment personnalisé référencé R.layout.bridge_layout_main, utilisez R.layout.capacitor_bridge_layout_main.
Edge-to-edge et le nouveau plugin System Bars
C’est le changement le plus visible. Capacitor 8 a supprimé android.adjustMarginsForEdgeToEdge et ajouté un plugin System Bars intégré. Vous n’avez pas à l’installer, il est fourni avec @capacitor/core.
Android 15 impose l'affichage edge-to-edge aux apps ciblant SDK 35, et Android 16 supprime l'option de désactivation pour les apps ciblant SDK 36. Capacitor 8 cible la version 36 : votre contenu web s'affiche donc désormais derrière les barres de statut et de navigation, sauf si vous gérez les insets.
La config du plugin se trouve sous plugins.SystemBars:
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'Example',
webDir: 'dist',
plugins: {
SystemBars: {
// 'css' (default) injects --safe-area-inset-* variables on Android
// 'native' relies on env() and viewport-fit
// 'disable' leaves inset handling entirely to you
insetsHandling: 'css',
initialViewportFitValueHint: 'cover',
},
},
};
export default config;
Avec css ou native, les WebViews Android plus récentes (Chromium 140+) respectent viewport-fit=cover et renvoient les vraies env(safe-area-inset-*) valeurs. Sur les WebViews plus anciennes, Capacitor initialise la WebView et définit les valeurs d'env sur 0px. Configurez donc la balise meta et utilisez les variables :
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
body {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
}
À l'exécution, vous pouvez modifier le style ou la visibilité des barres :
import { SystemBars, SystemBarsStyle, SystemBarType } from '@capacitor/core';
await SystemBars.setStyle({ style: SystemBarsStyle.Dark });
await SystemBars.hide({ bar: SystemBarType.NavigationBar });
Les apps Ionic Framework utilisent déjà les variables safe-area, elles n'ont donc généralement besoin que de la balise meta. Notre ancien article sur l'edge-to-edge sans plugins décrit l'option Capacitor 7, qui n'existe plus dans la version 8.
Autres changements de comportement à vérifier
appendUserAgentsur iOS: Capacitor 7 ajoutait deux espaces avant votre chaîne, Capacitor 8 en ajoute un. Si votre serveur analyse l'user agent strictement, ajoutez un espace en début de chaîne àios.appendUserAgent(et non l'option racine, qui affecte aussi Android).- Orientation de l'écran et scanner de codes-barres: sur Android 16+ et les grands écrans, les verrouillages d’orientation sont ignorés. Un opt-out temporaire est disponible via
android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITYpropriété du manifest, mais Android 17 la supprime. - géolocalisation:
timeouts’applique désormais à toutes les requêtes sur Android et iOS. Si vous constatez de nouveaux timeouts, augmentez la valeur.watchPositionsur Android a gagné uneintervaloption. - Barre d'état: le plugin n'expédie plus ses propres
CAPBridgeViewControllerfichiers de notification, car le cœur émet désormais ces événements. - Les nouvelles plateformes iOS utilisent SPM par défaut:
bunx cap add ioscrée désormais un projet SPM. Utilisez--packagemanager CocoaPodssi vous avez besoin de l'ancien modèle. Voir comment utiliser CocoaPods avec Capacitor 8.
Vérifier la mise à niveau
Parcourez cette liste sur les deux plateformes avant de déployer :
bunx cap doctor
bunx cap sync
bunx cap run ios
bunx cap run android
cap doctoraffiche les versions 8.x correspondantes pour le core, CLI, iOS et Android.- L’app se lance, l’écran de démarrage disparaît et les deep links ouvrent le bon écran.
- Les zones de la barre d’état et de la barre de navigation s’affichent correctement sur un appareil Android 15/16 et sur un iPhone avec encoche.
- Les notifications push, l’appareil photo, l’accès aux fichiers et tout plugin avec des permissions natives fonctionnent toujours.
- Un build de release (Archive dans Xcode,
./gradlew bundleRelease) réussit, pas seulement en debug.
Si vous ne voulez pas maintenir Xcode 26 et JDK 21 sur chaque machine, Build Capgo exécute les builds iOS et Android dans le cloud avec les toolchains actuelles.
Déployez l'upgrade en toute sécurité avec les live updates
Une mise à jour majeure de Capacitor modifie le code natif, elle doit donc passer par l’App Store et Google Play. Les bundles web générés après la mise à jour peuvent appeler des API de plugins que les anciens binaires ne possèdent pas.
Si vous utilisez les live updates Capgo, gardez séparés les utilisateurs de Capacitor 7 et ceux de Capacitor 8 jusqu’à ce que l’adoption suive : incrémentez votre version native, envoyez les nouveaux bundles sur un canal utilisé par le nouveau binaire, et lancez le contrôle de compatibilité avant l’upload :
bunx @capgo/cli@latest bundle compatibility
Il compare les versions des plugins natifs de votre bundle avec celles en cours sur le canal et signale les incompatibilités avant que les utilisateurs ne reçoivent une mise à jour cassée.
Dépannage des erreurs courantes de mise à niveau vers Capacitor 8
The engine "node" is incompatible ou le CLI refuse de s’exécuter. Vous utilisez Node 20 ou une version antérieure. Installez Node 22 LTS et mettez à jour votre image CI.
error: invalid source release: 21 sur Android. Gradle tourne avec le JDK 17. Faites pointer Android Studio vers son JDK 21 intégré (Paramètres > Build, Execution, Deployment > Build Tools > Gradle > Gradle JDK) et définissez JAVA_HOME sur un JDK 21 pour les builds en ligne de commande et CI.
Minimum supported Gradle version is 8.13. Vous avez mis à jour AGP mais pas le wrapper. Définissez le wrapper sur 8.14.3.
Dependency ... requires libraries and applications that depend on it to compile against version 36. compileSdkVersion est toujours à 35 quelque part. Vérifiez variables.gradle et tout plugin qui le code en dur.
Using 'kotlinOptions' ... is an error ou des erreurs Kotlin DSL similaires. Un plugin ou votre module d'application utilise encore kotlinOptions. Update the plugin, or patch it until a release lands (see comment patcher un plugin Capacitor).
Xcode : No such module 'Capacitor' après la mise à niveau. Pour CocoaPods, ouvrez App.xcworkspace, et non App.xcodeproj, et relancez bunx cap sync ios. Pour SPM, utilisez File > Packages > Reset Package Caches.
"X" plugin is not implemented on ios/android. Le plugin n’a pas été synchronisé, ou il n’a pas de release compatible Capacitor 8 / SPM. Exécutez bunx cap sync et lisez les avertissements.
Pour une liste plus longue, consultez le guide de dépannage iOS de Capacitor et le guide de dépannage Android. Les versions incompatibles du core et des plugins sont traitées dans corriger les erreurs de décalage de version Capacitor.
Laissez un agent IA gérer les tâches répétitives
Si vous utilisez Claude Code, Cursor ou un agent similaire, les skills Capgo open source incluent capacitor-app-upgrade-v7-to-v8 et capacitor-app-upgrades for multi-major jumps. Install them with bunx skills add Cap-go/capgo-skills et demandez à l’agent de mettre à jour l’application. Il exécute le migrateur, puis vérifie les étapes que CLI oublie souvent, comme la syntaxe Gradle, les options Kotlin et les images CI.
Ce qui suit
Capacitor 9 est déjà en préversion. Une fois stable sur la version 8, lisez Préparation à Capacitor 9 pour que la prochaine mise à niveau soit plus simple.