Skip to content
Back to skills

Capacitor App Upgrade V8 To V9

ASecurity

Upgrades a Capacitor app from v8 to v9 (prerelease, installed with @next until GA). Covers preflight (Node 24, Xcode 27, Android Studio 2026.1.1, UIScene adoption from 8.5), `npx cap migrate`, and the manual checklist - iOS 16 target, @UIApplicationMain to @main, removed CAPBridge APIs, AGP 9.2.1, Gradle 9.5.1, SDK 37/minSdk 26, gradle.properties cleanup, built-in Kotlin, jcenter removal, core-ktx, proguard-android.txt rename, optional Cordova runtime, `cap run --url`, push `alert` removal, s...

  • 72 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
ai-agentsgojavaswiftkotlinbashnodegitapi

Works with

  • cli
  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 5 files and shows the line behind each finding

Scanned October 11, 2026

npx -y skills add Cap-go/capgo-skills --skill capacitor-app-upgrade-v8-to-v9 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Capacitor App Upgrade V8 To V9?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Capacitor App Upgrade V8 To V9
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/cap-go-capacitor-app-upgrade-v8-to-v9/badge)](https://www.skillsdirectory.com/skills/cap-go-capacitor-app-upgrade-v8-to-v9)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: capacitor-app-upgrade-v8-to-v9
description: Upgrades a Capacitor app from v8 to v9 (prerelease, installed with @next until GA). Covers preflight (Node 24, Xcode 27, Android Studio 2026.1.1, UIScene adoption from 8.5), `npx cap migrate`, and the manual checklist - iOS 16 target, @UIApplicationMain to @main, removed CAPBridge APIs, AGP 9.2.1, Gradle 9.5.1, SDK 37/minSdk 26, gradle.properties cleanup, built-in Kotlin, jcenter removal, core-ktx, proguard-android.txt rename, optional Cordova runtime, `cap run --url`, push `alert` removal, splash fade default. Use for "upgrade to Capacitor 9", errors like "'@UIApplicationMain' is deprecated", "Could not find method jcenter()", getDefaultProguardFile('proguard-android.txt') failures, duplicate Kotlin plugin, duplicate class core-ktx, "unknown option '-l'". Do not use for 8.4 to 8.5 UIScene only (use capacitor-uiscene-migration), plugin libraries (use capacitor-plugin-upgrade-v8-to-v9), or older majors.
allowed-tools:
  - Bash(node -e *)
---

# Capacitor App Upgrade v8 to v9

Capacitor 9 is a prerelease (`next` dist-tag, 9.0.0-alpha.x as of October 2026). Install with `@next`; switch to `@latest` / `^9.0.0` once 9.0.0 is GA. Tell the user it is not GA before upgrading a production app, and work on a branch.

Canonical source: https://capacitorjs.com/docs/updating/9-0

## When to Use

TRIGGER when:
- App is on `@capacitor/core` 8.x and the user wants Capacitor 9
- Build errors after moving to Xcode 27 / Swift 6, AGP 9, or Gradle 9 in a Capacitor 8 app
- `npx cap run -l --host ...` no longer works (`--url` replaced it)
- Push notifications `presentationOptions: ['alert']` stopped showing banners on iOS
- Cordova-plugin-free app fails on `CapacitorCordova` / `com.getcapacitor.cordova` references after upgrading

Do not use:
- App still on 7 or older -> `capacitor-app-upgrades` (chain majors first)
- Only the 8.4 -> 8.5 UIScene step -> `capacitor-uiscene-migration`
- Plugin library repo -> `capacitor-plugin-upgrade-v8-to-v9`
- CocoaPods to SPM move -> `cocoapods-to-spm` (recommended, separate step)

## Live Project Snapshot

!`node -e "const fs=require('fs');if(!fs.existsSync('package.json'))process.exit(0);const pkg=JSON.parse(fs.readFileSync('package.json','utf8'));const out=[];for(const section of ['dependencies','devDependencies']){for(const [name,version] of Object.entries(pkg[section]||{})){if(name.startsWith('@capacitor/'))out.push(section+'.'+name+'='+version)}}out.push('node='+process.version);const p='ios/App/App/';out.push('ios.SceneDelegate='+fs.existsSync(p+'SceneDelegate.swift'));out.push('ios.Podfile='+fs.existsSync('ios/App/Podfile'));console.log(out.sort().join('\n'))"`

## Procedure

### 1. Preflight (stop and report if any fails)

```bash
node --version                     # must be >= 24
xcodebuild -version                # must be Xcode 27+
java -version                      # use the JDK bundled with Android Studio 2026.1.1+
grep -c UIApplicationSceneManifest ios/App/App/Info.plist
git status --short                 # clean tree, so the migration diff is reviewable
```

- Node < 24 or Xcode < 27: ask the user to upgrade tooling first.
- No scene manifest or no `SceneDelegate.swift`: the app has not adopted UIScene. Run the `capacitor-uiscene-migration` skill on 8.5 first, verify it, then return here. Doing both at once hides which step broke deep links.
- Inventory native customizations before migrating: custom `AppDelegate`/`SceneDelegate` code, custom `CAPBridgeViewController` subclass, local plugins in `ios/App/App` or `android/app/src`, extra variables in `variables.gradle`, Cordova plugins (`npx cap ls`).

### 2. Packages and automated migration

```bash
npm i -D @capacitor/cli@next
npx cap migrate
```

`cap migrate` updates dependencies and the template-shaped native files, and prints what it could not do. It is not built for monorepos; migrate those by hand. Then bump every other `@capacitor/*` package to `@next` (official plugins are 9.0.0 too) and check Capgo/third-party plugins for a Capacitor 9 compatible release (`npm view <pkg> peerDependencies`).

### 3. Manual checklist (verify each, even if migrate reported success)

- iOS -> `references/ios.md`: Xcode 27, iOS 16.0 in pbxproj + Podfile, `@main`, removed `CAPBridge`/bridge APIs in app code, SPM recommendation.
- Android -> `references/android.md`: gradle.properties cleanup, `variables.gradle` values, remove `targetSdkVersion`, `proguard-android-optimize.txt`, explicit `rootProject.ext` defs, core-ktx, Kotlin plugin removal, `jcenter()`, AGP 9.2.1, Gradle 9.5.1, google-services 4.5.0.
- Plugins, CLI, config -> `references/plugins-and-cli.md`: official plugin variable bumps, push `alert`, splash `launchFadeOutDuration`, `cap run --url`, Cordova runtime now optional.

### 4. Sync, build, verify

`npx cap sync`, then run everything in `references/verification.md`: leftover-symbol greps, both native builds, device checks. Report results per platform.

## Traps

- `android.builtInKotlin=false` or `android.sdk.defaultTargetSdkToCompileSdkIfUnset=false` left in `gradle.properties` (the AGP Upgrade Assistant writes them) breaks the build. Delete the whole AGP 8 compatibility block.
- `proguard-android.txt` fails at configuration time even with `minifyEnabled false`.
- Leaving `apply plugin: 'kotlin-android'` next to AGP 9's built-in Kotlin fails with a duplicate-plugin error, also inside local plugin modules.
- Apps with zero Cordova plugins no longer get `CapacitorCordova` / `capacitor-cordova-android`. Native code importing those symbols stops compiling; there is no flag to force-include them.
- Pre-UIScene AppDelegate code (`CAPBridge.handleOpenUrl`, `application(_:open:)` custom logic) both fails to compile and would never be called. Move it to the SceneDelegate.
- CocoaPods Trunk is expected to go read-only on December 2, 2026. Offer `cocoapods-to-spm` after the upgrade is green.

## Error Handling

| Error | Fix |
|---|---|
| `'@UIApplicationMain' is deprecated` (error in Swift 6 mode) | Replace with `@main` |
| `Cannot find 'CAPBridge' in scope` | Use `ApplicationDelegateProxy.shared` APIs (`references/ios.md`) |
| `Could not find method jcenter()` | Replace with `mavenCentral()` in every `build.gradle`, including local plugins |
| Configuration failure mentioning `proguard-android.txt` | Use `proguard-android-optimize.txt` |
| Kotlin plugin already applied / duplicate plugin `org.jetbrains.kotlin.android` | Remove `kotlin-android`, `kotlin-gradle-plugin` classpath, `kotlin-stdlib` |
| Duplicate class `androidx.core.*` (core-ktx) | Drop old `core-ktx`, depend on `androidx.core:core:1.19.0` |
| `Could not get unknown property 'androidxAppCompatVersion'` | Add `def x = rootProject.ext.x` at the top of `app/build.gradle` |
| Namespace collision between library modules | A plugin kept a scaffold/forked `namespace`; update or report that plugin |
| `error: unknown option '-l'` on `cap run` | `npx cap run <platform> --url http://<ip>:<port>` |
| `npm ERR! engine` / Node version error | Node 24+ |

## References

Only load a reference when its topic is in play.

| File | Load when |
|---|---|
| `references/ios.md` | Any iOS step or iOS build error |
| `references/android.md` | Any Android/Gradle step or build error |
| `references/plugins-and-cli.md` | Official plugin behavior changes, live reload, Cordova plugins |
| `references/verification.md` | After sync: greps, builds, device checklist |

Related skills: `capacitor-uiscene-migration`, `capacitor-app-upgrades`, `capacitor-plugin-upgrade-v8-to-v9`, `cocoapods-to-spm`, `capacitor-push-notifications`, `capacitor-splash-screen`.

Files in this skill

  • SKILL.md7.5 KB
  • references/android.md5.1 KB
  • references/ios.md3.2 KB
  • references/plugins-and-cli.md3.3 KB
  • references/verification.md3.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.