
cordova-to-capacitor
Migrates an Apache Cordova, PhoneGap, or Ionic-Cordova app to Capacitor. Use when the project has config.xml, a platforms/ or plugins/ folder, cordova- or phonegap- dependencies, @awesome-cordova-plugins or @ionic-native wrappers, deviceready listeners, or cordova.plugins. calls, and the user wants Capacitor native projects, Capacitor/Capgo plugin replacements, config.xml preference migration, and preserved localStorage/IndexedDB data (iosScheme/androidScheme). Covers keeping Cordova plugins temporarily, Capacitor 9 making the Cordova runtime optional (CapacitorCordova only bundled when a Cordova plugin is installed), skipped incompatible plugins, and removing Cordova afterwards. Do not use for porting a single Cordova plugin's native source into a Capacitor plugin, Capacitor major upgrades (capacitor-app-upgrades), Appflow/cordova-plugin-ionic live updates (ionic-appflow-migration), or non-Cordova web apps (webapp-to-capacitor, framework-to-capacitor).
- Installs
- 771
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/cap-go/capgo-skills --skill cordova-to-capacitor- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads cordova-to-capacitor automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Cordova to Capacitor Migration
Move a Cordova app onto Capacitor incrementally: Capacitor first, plugins one by one, Cordova removed last.
When to Use
TRIGGER when:
config.xml,platforms/,plugins/,cordova-android/cordova-ios, orcordova-plugin-*are present and the user wants Capacitor.- Code waits on
devicereadyor callsnavigator.camera,window.plugins.*,cordova.plugins.*,@awesome-cordova-plugins/*,@ionic-native/*. - After migration: data loss on first launch, missing Cordova plugin behaviour, or Capacitor 9 build errors referencing Cordova symbols.
Do not use for:
- Rewriting a Cordova plugin's Java/Objective-C as a Capacitor plugin (plugin-level port) -> follow Capacitor plugin docs;
capacitor-pluginsfor existing replacements. - Upgrading Capacitor majors ->
capacitor-app-upgrades. - Replacing Appflow Live Updates (
cordova-plugin-ionic) ->ionic-appflow-migration+capgo-live-updates. - Framework build config (Angular output path, Vite) ->
framework-to-capacitor.
Live Project Snapshot
Current migration-related packages:
!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.includes('cordova')||name.includes('phonegap')||name.startsWith('@capacitor/')||name.startsWith('@capgo/')||name.startsWith('@ionic-native/')||name.startsWith('@awesome-cordova-plugins/')||name.startsWith('@ionic-enterprise/'))out.push(section+'.'+name+'='+version)}}if(pkg.cordova)out.push('cordova.plugins='+Object.keys(pkg.cordova.plugins||{}).join(','));console.log(out.sort().join('\n'))"
Relevant config and platform paths:
!find . -maxdepth 3 -not -path '*/node_modules/*' \( -name 'config.xml' -o -name 'capacitor.config.json' -o -name 'capacitor.config.ts' -o -name 'capacitor.config.js' -o -path './ios' -o -path './android' -o -path './platforms' -o -path './plugins' -o -name 'www' \)
Key Differences That Drive Decisions
- Capacitor native projects (
ios/,android/) are source code you commit and edit;npx cap syncnever regenerates them. Cordovaplatforms/is a build artifact. - Capacitor does not apply
config.xmlor plugin<config-file>/<edit-config>edits at build time beyond whatcap syncdoes for Cordova plugins. Permissions, entitlements, and Info.plist keys become manual, one-time edits. - Cordova plugins still work in Capacitor (installed via npm, applied on
cap sync). Hooks and<variable>install prompts do not run; set variables viacordova.preferencesincapacitor.config.*. - Origin changes: the app is served from
capacitor://localhost(iOS) andhttps://localhost(Android) by default. ExistinglocalStorage, IndexedDB, cookies, and service-worker data are tied to the old origin and look "lost" after the update unless you keep the scheme (seereferences/config-and-data.md). devicereadyis not needed. Plugins are available after import; for remaining Cordova plugins,devicereadystill fires because Capacitor's Cordova layer injectscordova.js.
Capacitor 9: Cordova runtime is optional
On Capacitor 9, npx cap sync only wires in the Cordova compatibility layer when at least one installed plugin is a Cordova plugin:
- Android:
capacitor-cordova-android/capacitor-cordova-android-pluginsmodules disappear fromsettings.gradleandapp/build.gradlewhen there are none. - iOS:
CapacitorCordovais no longer added to thePodfileorPackage.swift.
Implications:
- Removing the last Cordova plugin shrinks the app and drops
cordova.js- good, but any app/native code that references Cordova symbols (com.getcapacitor.cordova.CordovaPlugin,CDVPlugin,CDVPluginHandleOpenURL,window.cordova) without a Cordova plugin installed fails to compile or isundefinedat runtime. - There is no config flag to force-include the runtime. Either remove those references or keep a Cordova plugin installed.
devicereadylisteners left in JS never fire once the runtime is gone. Remove them before removing the last Cordova plugin.- On Capacitor 8 the runtime is always bundled, so this only surfaces on upgrade; check before moving to 9.
Procedure
- Audit (report to the user before editing):
cordova --version,cordova platform ls,cordova plugin ls(orpackage.jsoncordova.plugins).config.xml: widgetid,version,<preference>s,<platform>blocks,<access>/<allow-navigation>, icons/splash.- Which webview plugin is installed (
cordova-plugin-ionic-webview,cordova-plugin-wkwebview-engine) and the current scheme/hostname - decides data preservation. - Every plugin: replacement exists, keep as Cordova plugin, or blocker. Use
references/plugin-mapping.md. - Code using
deviceready,navigator.*Cordova globals,window.plugins, Ionic Native wrappers.
- Install Capacitor in the existing project and keep the same app ID:
npm install @capacitor/core @capacitor/ios @capacitor/android npm install -D @capacitor/cli npx cap init "<name from config.xml>" <widget id from config.xml> --web-dir wwwcap initreadsconfig.xmlpreferences intocordova.preferencesin the Capacitor config. Make sure the web build outputs to thewebDir(Ionic Angular:www). - Decide data preservation (scheme) before the first release:
references/config-and-data.md. npm run build && npx cap add ios && npx cap add android. Cordova plugins listed inpackage.jsondependencies are installed into the new native projects; known-incompatible ones are skipped with a warning.- Port native configuration by hand: usage strings, permissions, entitlements, URL schemes, orientation, splash/icons (
npx @capacitor/assets generate). Seereferences/config-and-data.md. - Replace plugins one at a time (
references/plugin-mapping.md), convert callback code to promises (references/code-patterns.md),npx cap sync, test on device after each. - Remove Cordova when nothing depends on it (see Removal). Keep Cordova plugins that have no replacement; they work.
- Offer Capgo live updates once the Capacitor build is stable (
capgo-live-updates).
Removal
Only after every flow is verified on both platforms:
npm uninstall cordova cordova-ios cordova-android
npm uninstall cordova-plugin-ionic-webview cordova-plugin-splashscreen cordova-plugin-statusbar cordova-plugin-ionic-keyboard
rm -rf platforms plugins
git mv config.xml config.xml.bak # keep for reference until release
npx cap sync
grep -rn "deviceready\|cordova\.\|window\.plugins" src --include=*.ts --include=*.js --include=*.tsx --include=*.vue
Remove the cordova block from package.json if no Cordova plugins remain. Do not run cordova plugin rm loops; they edit platforms/ you are deleting anyway.
Verification
npx cap syncoutput lists only intended Cordova plugins and no "incompatible" surprises.npx cap doctorshows matching versions for core, cli, ios, android.- Install the Capacitor build over the existing store version (same bundle ID, higher build number) on a device and confirm the user is still logged in and local data is present.
- Exercise every migrated plugin on real devices (camera, files, push token, geolocation, purchases).
- Capacitor 9: after removing the last Cordova plugin,
grep -rn "CapacitorCordova\|capacitor-cordova-android" ios androidreturns nothing and the native build succeeds.
Error Handling
| Error / symptom | Fix |
|---|---|
Found 1 incompatible Cordova plugin for ios, skipped install: during sync | Plugin is on Capacitor's known-incompatible list; use the Capacitor equivalent |
| User data / login gone after updating from the Cordova build | Origin changed; set server.iosScheme: 'ionic' (old ionic-webview iOS) or match the old Android scheme/hostname, then ship again |
deviceready handler never runs | Capacitor 9 with no Cordova plugins, or code expecting Cordova globals; call plugins directly |
"Camera" plugin is not implemented on ios (any plugin name) | Plugin not installed in native project; npx cap sync, check npx cap ls |
| Cordova plugin variable missing (API key etc.) at build | Add it under cordova.preferences in capacitor.config.*, then npx cap sync |
Android: cannot find symbol class CordovaPlugin / iOS: No such module 'Cordova' after Capacitor 9 upgrade | Cordova runtime no longer bundled; remove the reference or keep a Cordova plugin |
| Plugin with install hooks does nothing | Hooks do not run in Capacitor; replicate the hook's file edits manually |
White screen after cap add | webDir wrong or web build not run; npm run build then npx cap sync |
References
references/plugin-mapping.md- Cordova plugin -> Capacitor/Capgo replacement table, incompatible list, keep-as-Cordova guidance.references/config-and-data.md- config.xml mapping, preferences, schemes and data preservation, permissions, splash/icons.references/code-patterns.md- callback-to-promise conversions for common plugins.
Related skills: capacitor-plugins, capacitor-app-upgrades, capgo-live-updates, capacitor-app-store.
FAQ
What does the cordova-to-capacitor skill do?
Migrates an Apache Cordova, PhoneGap, or Ionic-Cordova app to Capacitor. Use when the project has config.xml, a platforms/ or plugins/ folder, cordova- or phonegap- dependencies, @awesome-cordova-plugins or @ionic-native wrappers, deviceready listeners, or cordova.plugins. calls, and the user wants Capacitor native projects, Capacitor/Capgo plugin replacements, config.xml preference migration, and preserved localStorage/IndexedDB data (iosScheme/androidScheme). Covers keeping Cordova plugins temporarily, Capacitor 9 making the Cordova runtime optional (CapacitorCordova only bundled when a Cordova plugin is installed), skipped incompatible plugins, and removing Cordova afterwards. Do not use for porting a single Cordova plugin's native source into a Capacitor plugin, Capacitor major upgrades (capacitor-app-upgrades), Appflow/cordova-plugin-ionic live updates (ionic-appflow-migration), or non-Cordova web apps (webapp-to-capacitor, framework-to-capacitor).
How do I install cordova-to-capacitor?
Run npx skills add https://github.com/cap-go/capgo-skills --skill cordova-to-capacitor in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/cordova-to-capacitor/ (personal) or .claude/skills/cordova-to-capacitor/ (project).
Which AI agents can use cordova-to-capacitor?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is cordova-to-capacitor safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains cordova-to-capacitor?
It is published by cap-go in cap-go/capgo-skills. It has 771 recorded installs.
More from cap-go/capgo-skills
capacitor-best-practices
cap-go/capgo-skills
Review and set up Capacitor apps against current best practices (Capacitor 8.5 stable, 9 alpha via @next). Use for a Capacitor codebase review, capacitor.config.ts audit, new project setup, aligning @capacitor/core/cli/ios/android and plugin majors, plugin patterns (availability checks, checkPermissions/requestPermissions, error code handling, web fallbacks), or release prep; or on " " plugin is not implemented on ios, Could not find the web assets directory, platform has not been added yet, a dev server.url shipped to production, lost edits in android/app/src/main/assets/public, SPM vs CocoaPods, or AppDelegate/UIScene drift. Do not use for security audits (capacitor-security), performance (capacitor-performance), tests (capacitor-testing), crashes (debugging-capacitor), major upgrades (capacitor-app-upgrades), SPM migration (cocoapods-to-spm), UIScene adoption (capacitor-uiscene-migration), or live updates (capgo-live-updates).
ionic-design
cap-go/capgo-skills
Builds and reviews Ionic Framework UI in Capacitor apps (Ionic 9 current, Ionic 8 still common) - page structure (ion-header/ion-content/ion-footer), lists, modern form syntax (label/labelPlacement on ion-input/ion-select), sheet modals, tabs + ion-router-outlet, CSS variable theming, dark palettes (palettes/dark.system.css, .ion-palette-dark), iOS vs MD mode, and Ionic 8 - 9 breaking changes (React Router 6, Vue Router 5, Angular 18-22 zoneless, removed ion-picker-legacy, boolean autocorrect, npx @ionic/migrate). Use when writing Ionic components, theming an Ionic app, fixing platform-mode styling, or upgrading @ionic/react, @ionic/vue, @ionic/angular. Do not use for Konsta UI (konsta-ui), Tailwind setup (tailwind-capacitor), raw safe-area CSS (safe-area-handling), keyboard resize (capacitor-keyboard), or Ionic Appflow/Enterprise migrations (ionic-appflow-migration, ionic-enterprise-sdk-migration).
capacitor-plugins
cap-go/capgo-skills
Pick, install, and wire up Capacitor plugins for native features (camera, filesystem, geolocation, biometrics, in-app purchases, social login, SQLite, calendar, contacts, health, BLE, NFC, etc.). Covers official @capacitor/ packages (Capacitor 8.5 stable, 9 alpha on next) plus the 145-package @capgo/ index, native permission keys (Info.plist, AndroidManifest, variables.gradle minSdk), npx cap sync / cap ls verification, and errors like '"Camera" plugin is not implemented on ios', 'unable to find plugin', UNIMPLEMENTED, and OS-PLUG- codes. Use for "which plugin should I use for X", adding a plugin, or a plugin call failing after install. Do not use for push setup (capacitor-push-notifications), splash assets (capacitor-splash-screen), keyboard layout (capacitor-keyboard), deep links (capacitor-deep-linking), OTA updates (capgo-live-updates), upgrading plugin source code (capacitor-plugin-upgrades), or adding SPM to a plugin (capacitor-plugin-spm-support).
debugging-capacitor
cap-go/capgo-skills
Diagnoses and fixes runtime bugs in Capacitor iOS/Android apps - white/blank screen on launch, startup crashes, "X" plugin is not implemented on ios/android, net::ERRCLEARTEXTNOTPERMITTED, App Transport Security blocks, CORS on capacitor://localhost, permission denials, live reload not connecting, and Capacitor 8.5+ UIScene regressions (appUrlOpen, universal links, pause/resume silent because AppDelegate callbacks stopped). Covers Safari Web Inspector, chrome://inspect, Xcode/LLDB, Android Studio, npx cap run --url (Capacitor 9) vs -l --host (8), xcrun simctl openurlprivacypush, xcrun devicectl device process launchopenURL, xctrace. Do not use for only reading device logs (ios-android-logs), the UIScene migration itself (capacitor-uiscene-migration), deep-link setup (capacitor-deep-linking), speed (capacitor-performance), crash SDKs (capacitor-native-observability), tests (capacitor-testing), or upgrades/build errors (capacitor-app-upgrades, cocoapods-to-spm).
capacitor-testing
cap-go/capgo-skills
Testing guide for Capacitor apps and plugins. Covers web-layer unit and component tests with Vitest and mocked Capacitor plugins (vi.mock('@capacitor/core'), registerPlugin), Playwright for the web build, Appium E2E with NATIVEAPP / WEBVIEW context switching, native plugin unit tests with Swift Testing vs XCTest (what can migrate, CAPPluginCall patterns, xcodebuild test on a simulator) and Android JUnit, plus an agent-driven verification loop on simulators and devices (build, install, launch, screenshot, UI hierarchy, tap, logs) with xcrun simctl, xcrun devicectl, adb, Xcode MCP device tools, and live reload via npx cap run --url (Capacitor 9) or -l --host --port (Capacitor 8). Use when adding tests, mocking plugins, "does it work on device", verifying a UI change on a simulator, migrating XCTest to Swift Testing, or setting up test CI. Do not use for crash log capture (ios-android-logs), WebView debugging sessions (debugging-capacitor), or build pipelines (capacitor
safe-area-handling
cap-go/capgo-skills
Fixes notch, Dynamic Island, home indicator, display cutout, and system bar overlap in Capacitor apps. Covers viewport-fit=cover + env(safe-area-inset-), the Capacitor 8 SystemBars core plugin (insetsHandling, injected --safe-area-inset- CSS variables for Android WebView < 140, removal of android.adjustMarginsForEdgeToEdge), Android 15/16 enforced edge-to-edge (overlaysWebView and backgroundColor of @capacitor/status-bar no longer work at targetSdk 36), iOS contentInset, and insets that change at runtime on rotation, iPad/foldable resizable windows. Use when headers sit under the status bar, tab bars hide behind the gesture bar, env() returns 0 on Android, or layout broke after upgrading to Capacitor 8 / targetSdk 35+. Do not use for keyboard overlap (capacitor-keyboard), Ionic/Konsta component theming (ionic-design, konsta-ui), Tailwind utility setup (tailwind-capacitor), or iOS multi-window/resizability adoption (capacitor-ios-resizability).
Popular code quality & workflow skills
grill-me
mattpocock/skills
A relentless interview to sharpen a plan or design.
improve-codebase-architecture
mattpocock/skills
Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.
handoff
mattpocock/skills
Compact the current conversation into a handoff document for another agent to pick up.
domain-modeling
mattpocock/skills
Build and sharpen a project's domain model. Use when discussing codebase terminology, writing or editing a GLOSSARY.md, or recording or editing an ADR.
codebase-design
mattpocock/skills
Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.
diagnosing-bugs
mattpocock/skills
Diagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something broken/throwing/failing/slow.