Migrate in stages, each ending in a build you can install, test and commit. The notes app took four:
Add Capacitor 243,123 beside Cordova 129 . Install @capacitor/core, @capacitor/cli and @capacitor/android, run npx cap init with the Cordova app's name, id and web folder (built first, if the app has a build step), then npx cap add android.
Run the Cordova plugins through the compatibility layer, fixing what Cordova Plugin Variables-Compatibility Limits point to. This build is shippable: the app's JavaScript has not changed.
Replace plugins one at a time with Capacitor equivalents (Replacing Cordova Plugins).
Remove Cordova (Removing Cordova), then generate icons and splash screens with @capacitor/assets (Status Bar and Splash Screen), since config.xml's <icon> and <splash> entries are not migrated.
First inventory every plugin and variable (package.json's cordova block), every <preference> and <edit-config> in config.xml, and any hooks. Then check identity: the appId must equal the Cordova widget id, and the version code must be higher, or users get a second app or no update. Cordova computes versionCode from version="1.0.0" as 10000, while Capacitor's template starts at 1, so the first install attempt over the Cordova app failed:
adb: failed to install app/build/outputs/apk/debug/app-debug.apk: Failure
[INSTALL_FAILED_VERSION_DOWNGRADE: Downgrade detected: Update version code 1 is older than
current 10000]Setting versionCode 10100 and versionName "1.1.0" in android/app/build.gradle fixed it; Google Play 1 refuses the same downgrade. The signing key must match too. Both debug APKs used the same debug keystore (apksigner printed the same SHA-256 digest), and a release needs the Cordova app's upload key (Release Signing).