capacitor-plugin-upgrade-v4-to-v5
About capacitor-plugin-upgrade-v4-to-v5
A skill for migrating Capacitor plugin libraries from v4 to v5. It guides package, Android, and iOS updates, with checks for nullability and native build requirements.
Key features
- 01Project snapshot and version checks
- 02Automated migration command
- 03Manual Android and iOS update guidance
- 04Build and migration verification
Use cases
- 01Preparing a v4 plugin for Capacitor 5 apps
- 02Fixing Android namespace or Java 17 build errors
- 03Updating plugin bridge code for Capacitor 5
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ cap-go/ capgo-skills --skill capacitor-plugin-upgrade-v4-to-v5After installing, type/capacitor-plugin-upgrade-v4-to-v5in Claude Code to confirm it loaded.
Bundled filesmetadata.jsonreferences/android.md
Details
From the project READMECapacitor Plugin Upgrade v4 to v5
Move a plugin library to Capacitor 5. Source of truth: https://capacitorjs.com/docs/updating/plugins/5-0
When to Use
- Snapshot shows
@capacitor/core4.x in peer/dev deps and the plugin must work in Capacitor 5 apps. - A Capacitor 5 app fails building this plugin with
Namespace not specifiedor Java 17 errors. - The plugin manually conforms to
CAPBridgedPluginor callsgetObject()/getArray().
Do not use:
- Upgrading an app ->
capacitor-app-upgrade-v4-to-v5. - Plugin already on 5 ->
capacitor-plugin-upgrade-v5-to-v6. Multi-hop ->capacitor-plugin-upgrades.
Live Project Snapshot
Plugin and Capacitor package 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=['package.name='+(pkg.name||''),'package.version='+(pkg.version||'')];for(const section of ['peerDependencies','dependencies','devDependencies']){for(const [name,version] of Object.entries(pkg[section]||{})){if(name.startsWith('@capacitor/'))out.push(section+'.'+name+'='+version)}}console.log(out.join('\n'))"
Example and native project paths:
!find . -maxdepth 3 \( -path './example-app' -o -path './ios' -o -path './android' \)
References
| File | Load when |
|---|---|
references/android.md | Applying Gradle, manifest, Java or Kotlin changes by hand |
Preflight
| Tool | Minimum |
|---|---|
| Node.js | 16+ |
| Xcode | 14.1+ |
| Java | 17 (AGP 8) |
| AGP / Gradle | 8.0.0 / 8.0.2 |
| Android SDK defaults | compileSdk 33, targetSdk 33, minSdk 22 |
| iOS deployment target | 13.0 (unchanged) |
Procedure
-
Confirm the plugin is on 4.x from the snapshot and the tree is clean (
git status). -
From the plugin root run:
npx @capacitor/plugin-migration-v4-to-v5@latestIt edits
package.json,android/build.gradle, the wrapper,gradle.properties, and the manifest. Reviewgit diff. -
Finish manually anything not applied (
references/android.md):@capacitor/cli,core,android,iosdev deps tolatest-5; peer@capacitor/coreto^5.0.0.- SDK defaults 33, AGP 8.0.0, Gradle 8.0.2,
namespaceinandroid {}and nopackage=in the manifest, Java 17, Jetifier removed, Kotlin 1.8.20 withkotlin-stdlib.
-
iOS code: if the plugin conforms to
CAPBridgedPluginmanually (noCAP_PLUGINmacro), move requirements to instance level, renamepluginIdtoidentifier, typepluginMethodsas[CAPPluginMethod], and dropgetMethod(_:). Macro-based plugins need no change. -
Android code:
call.getObject(key)andcall.getArray(key)can now returnnull. Add null checks andcall.reject(...)with a clear message when required. -
Update the example app (if present) to Capacitor 5 via
capacitor-app-upgrade-v4-to-v5. -
Bump the plugin major version and note "Requires Capacitor 5" in the changelog/README.
Verification
grep -n "\"@capacitor/" package.json # 5.x everywhere
grep -n "package=" android/src/main/AndroidManifest.xml # expect none
grep -n "namespace\|VERSION_17\|gradle:8.0.0" android/build.gradle
grep -rn "kotlin-stdlib-jdk" android/build.gradle # expect none
grep -rn "getObject(\|getArray(" android/src/main/ # each result null-checked
grep -rn "pluginId\b" ios/ # only CAPPlugin usages remain
npm run build
npm run verify # plugin template script: verify:ios + verify:android + verify:web, if present
cd android && ./gradlew clean build test
Run the example app on both platforms and exercise every method.
Error Handling
| Error | Fix |
|---|---|
Namespace not specified | Add namespace "<package>" to android {} in the plugin build.gradle. |
Android Gradle plugin requires Java 17 to run | Switch the Gradle JDK to 17. |
NullPointerException from getObject/getArray | Add null checks (step 5). |
Swift: type does not conform to protocol CAPBridgedPlugin | Use instance-level identifier, jsName, pluginMethods, or switch to the macro. |
Duplicate class ... kotlin-stdlib-jdk8 | Replace kotlin-stdlib-jdk7/jdk8 with kotlin-stdlib. |