mcpField
C
capacitor-plugin-upgrade-v8-to-v9

capacitor-plugin-upgrade-v8-to-v9

github.com/cap-goDevelopment7352 installsUpdated 2w ago
Repository

About capacitor-plugin-upgrade-v8-to-v9

A skill for updating Capacitor plugin projects from version 8 to version 9. It addresses dependency ranges, native API removals, build files, optional Cordova support, and checks using an example app.

Key features

  1. 01Plugin migration preflight
  2. 02Automated migration tool
  3. 03Android and iOS API updates
  4. 04CocoaPods and SPM build files
  5. 05Cordova dependency adjustments
  6. 06Example app and release verification

Use cases

  1. 01Adding Capacitor 9 support to a plugin
  2. 02Resolving native compilation failures
  3. 03Preparing plugin changes for release

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/cap-go/capgo-skills --skill capacitor-plugin-upgrade-v8-to-v9

After installing, type/capacitor-plugin-upgrade-v8-to-v9in Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

metadata.json
references/
android-api-removals.md
build-files.md
ios-api-removals.md
verification.md

Details

From the project README

Capacitor Plugin Upgrade v8 to v9

Capacitor 9 is a prerelease (next dist-tag, 9.0.0-alpha.x as of October 2026). Dependency ranges below target the prerelease; after 9.0.0 GA use ^9.0.0 / from: "9.0.0". Tell the user before publishing a stable plugin release that only supports a prerelease core; a common choice is to publish it under an npm next tag.

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

When to Use

TRIGGER when:

  • Plugin repo with peerDependencies["@capacitor/core"] at ^8 or >=8 and the user wants Capacitor 9 support
  • Plugin fails to compile against Capacitor 9 on removed APIs (CAPBridge, @NativePlugin, saveCall, getWebView(), isSimulator())
  • Plugin's android/build.gradle fails under AGP 9 / Gradle 9 (jcenter(), kotlin-android, proguard-android.txt, namespace collision)
  • A consuming app without Cordova plugins fails on the plugin's Cordova SPM product or com.getcapacitor.cordova imports

Do not use:

  • App projects -> capacitor-app-upgrade-v8-to-v9
  • Plugin still on 7 or older -> capacitor-plugin-upgrades (chain majors)
  • Adding SPM to a CocoaPods-only plugin -> capacitor-plugin-spm-support
  • Only checking a plugin against the 8.5 UIScene lifecycle -> capacitor-uiscene-migration (references/plugin-audit.md)

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=['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)}}out.push('Package.swift='+fs.existsSync('Package.swift'));out.push('podspec='+fs.readdirSync('.').filter(f=>f.endsWith('.podspec')).join(','));console.log(out.join('\n'))"

!find . -maxdepth 3 \( -path './example-app' -o -path './example' -o -path './ios' -o -path './android' \) -not -path './node_modules/*'

Procedure

  1. Inspect. Read the snapshot, android/build.gradle, android/gradle.properties, the .podspec, Package.swift, and list native sources (android/src/main, ios/Sources or ios/Plugin). Note the example app path. Confirm the tree is clean (git status).
  2. Run the migrator from the plugin root:
    npx @capacitor/plugin-migration-v8-to-v9@latest
    
    Review the diff (git diff). It covers most file edits, not API removals in your code.
  3. Dependencies in package.json:
    • devDependencies: @capacitor/cli, @capacitor/core, @capacitor/android, @capacitor/ios -> next.
    • peerDependencies["@capacitor/core"]: >=9.0.0-alpha.6 (check npm view @capacitor/core dist-tags for the current prerelease). Ask whether the release should still support 8; most plugins drop it because iOS 16 / AGP 9 build changes are not backward compatible.
  4. Build files per references/build-files.md (gradle.properties, build.gradle, podspec, Package.swift). Keep both podspec and Package.swift: apps on CocoaPods and SPM both consume the plugin.
  5. Code API removals. Grep, then fix each hit with references/android-api-removals.md and references/ios-api-removals.md. Do not leave deprecated call paths behind #if or reflection.
  6. Cordova optionality. Remove the unconditional .product(name: "Cordova", ...) from Package.swift. If the plugin's native code imports Cordova compatibility classes (com.getcapacitor.cordova.*, CDV*) it will break in apps without Cordova plugins; ask the user how to replace it.
  7. UIScene lifecycle. Every Capacitor 9 app is scene-based. Audit iOS code for AppDelegate-method assumptions, tmpWindow, keyWindow presentation, applicationState (see capacitor-uiscene-migration -> references/plugin-audit.md). Since the minimum is now 9, .capacitorScene* notifications and SceneDelegateProxy are safe to use.
  8. Example app and docs. Upgrade the example app with capacitor-app-upgrade-v8-to-v9. Update README install/compat tables (Capacitor 9, iOS 16, minSdk 26).
  9. Verify with references/verification.md. Bump the plugin major version.

Traps

  • AGP 9 defaults android.uniquePackageNames=true: a scaffold default namespace (com.mycompany.plugins.example) or a fork that kept the upstream namespace now fails the consuming app's build. Make it unique.
  • targetSdkVersion in a library module has no runtime effect; delete it rather than bumping.
  • CapacitorUrlRequest.setRequestHeaders([String: Any]) sets values instead of appending; repeated header keys now overwrite.
  • Package.swift must point at capacitor-swift-pm from: "9.0.0-alpha.6" or later (earlier alphas had Cordova-optionality crashes). Use the newest alpha.
  • googleMapsUtilsVersion 5.0.0 carries upstream breaking API changes.
  • Running npx cap sync from the plugin root does nothing useful; sync inside the example app.

Error Handling

ErrorFix
cannot find symbol ... class NativePlugin@CapacitorPlugin(name = ..., permissions = ...)
cannot find symbol ... method saveCall(PluginCall)call.setKeepAlive(true) or bridge.saveCall(call)
cannot find symbol ... method pluginRequestPermission(...)requestPermissionForAlias(alias, call, "callbackName") + @PermissionCallback
Cannot find 'CAPBridge' in scopeApplicationDelegateProxy.shared / Notification.Name.capacitorStatusBarTapped
Value of type 'CAPBridgeProtocol' has no member 'getWebView'bridge?.webView (same pattern for other getters -> properties)
Duplicate or conflicting Kotlin plugin error under AGP 9Remove standalone Kotlin plugin and stdlib
Namespace collision / duplicate package in consuming appUnique namespace in android/build.gradle
SPM resolution or link error mentioning Cordova in a consuming appRemove the Cordova product dependency

References

Only load a reference when its topic is in play.

FileLoad when
references/build-files.mdEditing gradle.properties, build.gradle, podspec, Package.swift, wrapper
references/android-api-removals.mdAny Java/Kotlin compile error or grep hit
references/ios-api-removals.mdAny Swift/ObjC compile error or grep hit
references/verification.mdAfter edits: greps, builds, example-app checks, publish

Related skills: capacitor-plugin-upgrades, capacitor-app-upgrade-v8-to-v9, capacitor-uiscene-migration, capacitor-plugin-spm-support.

Comments

Markdown supported