skills/capacitor-plugin-development/SKILL.md
Guides the agent through creating and maintaining Capacitor plugins from scratch. Covers scaffolding a new plugin project, designing the TypeScript API, implementing native iOS (Swift) and Android (Java/Kotlin) bridges, implementing the web layer, defining TypeScript type definitions, plugin configuration values, plugin hooks, development workflow with local testing, documentation generation, and publishing to npm. Do not use for installing existing plugins into an app, upgrading existing plugins to newer Capacitor versions, adding SPM support to plugins, or non-Capacitor plugin frameworks.
npx skillsauth add capawesome-team/skills capacitor-plugin-developmentInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create and maintain Capacitor plugins — scaffolding, native API bridging (iOS/Android), type definitions, testing, and publishing.
| Requirement | Version | | --- | --- | | Node.js | LTS (18+) | | npm | 6+ | | Xcode | 15+ (for iOS) | | Android Studio | Hedgehog 2023.1.1+ (for Android) | | Capacitor | 6+ |
package.json, inspect the directory structure, and infer the plugin's current state before prompting the user.Ask the user what they want to do. Common tasks:
references/plugin-configuration.md and apply.references/testing-and-workflow.md (Plugin Hooks section) and apply.If the user's intent is clear from context, skip this question and proceed directly.
Read references/scaffolding.md and guide the user through generating a new plugin project using the Capacitor plugin generator.
Gather the following from the user (or infer from context):
Run the generator and verify the scaffold with npm run verify.
Read references/designing-api.md and guide the user through defining the plugin interface.
src/definitions.ts.src/index.ts using registerPlugin().Ensure:
@since tags.Read references/web-guide.md and implement the web layer in src/web.ts.
WebPlugin and implement the plugin interface.this.unimplemented().this.unavailable() if missing.After implementation, build and verify:
npm run build
npm run verify:web
Before implementing native code, determine the method types for each plugin method:
| Type | TypeScript | iOS | Android |
| --- | --- | --- | --- |
| Returns a value | Promise<T> | CAPPluginReturnPromise | @PluginMethod() |
| Returns void | Promise<void> | CAPPluginReturnNone | @PluginMethod(returnType = PluginMethod.RETURN_NONE) |
| Callback (repeated) | Promise<string> | CAPPluginReturnCallback | @PluginMethod(returnType = PluginMethod.RETURN_CALLBACK) |
Most methods use the "returns a value" type. Use "callback" only for continuous data streams (e.g., geolocation watching).
Read references/ios-guide.md and implement the iOS layer.
ios/Sources/<ClassName>Plugin/Example.swift) with the platform logic. Extend NSObject and mark methods with @objc.ios/Sources/<ClassName>Plugin/ExamplePlugin.swift):
CAPPlugin and conform to CAPBridgedPlugin.identifier, jsName, and pluginMethods properties.@objc func method, reading data from CAPPluginCall and calling resolve(), reject(), unavailable(), or unimplemented()..podspec file.checkPermissions() and requestPermissions(), and document the required Info.plist keys.After implementation, verify:
npm run verify:ios
Read references/android-guide.md and implement the Android layer.
android/src/main/java/<package-path>/Example.java) with the platform logic.android/src/main/java/<package-path>/ExamplePlugin.java):
Plugin and add @CapacitorPlugin(name = "<JSName>").@PluginMethod method, reading data from PluginCall and calling resolve(), reject(), unavailable(), or unimplemented().android/build.gradle.@CapacitorPlugin annotation.checkPermissions() and requestPermissions().AndroidManifest.xml.After implementation, verify:
npm run verify:android
If the plugin emits events to JavaScript:
addListener() and removeAllListeners() methods to the plugin interface in src/definitions.ts. Define an event interface for each event type.this.notifyListeners('eventName', data) when the event occurs.self.notifyListeners("eventName", data: [...]) when the event occurs. Register observers in load() if listening to system notifications.notifyListeners("eventName", jsObject) when the event occurs. Override handleOnConfigurationChanged() or register broadcast receivers as needed.Ensure the event name string is identical across all platforms and matches the eventName parameter in addListener().
src/definitions.ts if not already present.npm run docgen
npm run verify
npm run lint
npm run fmt
Read references/publishing.md and guide the user through the publishing process.
package.json fields are correct (name, version, description, files, capacitor).npm publish --access public
npm init @capacitor/plugin@latest fails: Ensure Node.js LTS and npm 6+ are installed. Run node -v and npm -v to check.npm run verify:ios fails with "module not found": Run cd ios && pod install --repo-update && cd .. to install CocoaPods dependencies.npm run verify:android fails with build errors: Open android/ in Android Studio, sync Gradle, and check for missing dependencies or SDK version mismatches.npm run build fails with TypeScript errors: Check src/definitions.ts for type mismatches. Ensure the web implementation in src/web.ts correctly implements the plugin interface.registerPlugin() name mismatch: The first argument to registerPlugin() in src/index.ts must exactly match the jsName property on iOS and the @CapacitorPlugin(name = "...") value on Android. A mismatch causes the plugin to not load.@objc and listed in the pluginMethods array of CAPBridgedPlugin.@PluginMethod() annotation and are public.notifyListeners() call and the TypeScript addListener() definition. Verify addListener() is called before the event fires.getConfig().getString("key") match the keys in the Capacitor config file under plugins.<PluginJSName>.npm run docgen produces empty output: Ensure JSDoc comments are present on the plugin interface methods in src/definitions.ts, not on the implementation classes.capacitor-plugin-spm-support — Add Swift Package Manager support to a Capacitor plugin.capacitor-plugin-upgrades — Upgrade a Capacitor plugin to a newer Capacitor major version.capacitor-plugins — Install and configure existing Capacitor plugins in an app project.tools
Guides the agent through migrating Capacitor apps from discontinued Ionic Enterprise SDK plugins (Auth Connect, Identity Vault, Secure Storage) to their Capawesome alternatives (OAuth, Vault, Biometrics, Secure Preferences, SQLite). Covers dependency detection, side-by-side API mapping, code replacement, and platform-specific configuration for each plugin pair. Do not use for migrating Capacitor apps or plugins to a newer version, setting up Capawesome Cloud, or non-Capacitor mobile frameworks.
tools
Guides the agent through installing, configuring, and using Capacitor plugins from six sources — official Capacitor plugins, Capawesome plugins, Capacitor Community plugins, Capacitor Firebase plugins, Capacitor MLKit plugins, and RevenueCat plugins. Covers installation, platform-specific configuration (Android and iOS), and basic usage examples. Do not use for migrating Capacitor apps or plugins to a newer version, setting up Capacitor Live Updates, or non-Capacitor mobile frameworks.
tools
Guides the agent through Ionic Vue development patterns — project structure, Vue-specific Ionic components (IonPage, IonRouterOutlet, IonTabs), navigation with Vue Router and useIonRouter, Ionic lifecycle hooks (onIonViewWillEnter, onIonViewDidEnter, onIonViewWillLeave, onIonViewDidLeave), composable utilities (useIonRouter, useBackButton, useKeyboard), tab-based routing, lazy loading, platform detection with isPlatform, and troubleshooting common Vue-specific issues. Do not use for general Ionic component theming or CLI usage (use ionic-app-development), creating a new Ionic app (use ionic-app-creation), Capacitor-specific Vue patterns without Ionic (use capacitor-vue), upgrading Ionic versions (use ionic-app-upgrades), or non-Vue frameworks like Angular or React.
development
Guides the agent through Ionic Framework development with React — project structure, React-specific Ionic components, IonReactRouter and navigation patterns, Ionic lifecycle hooks (useIonViewWillEnter, useIonViewDidEnter, useIonViewWillLeave, useIonViewDidLeave), state management integration, and React-specific best practices for Ionic apps. Do not use for plain Capacitor React apps without Ionic (use capacitor-react), Ionic with Angular or Vue, creating a new Ionic app (use ionic-app-creation), upgrading Ionic to a newer version (use ionic-app-upgrades), or general Ionic component usage without React-specific context (use ionic-app-development).