capacitor-plugin-spm-support
Adds Swift Package Manager support to an existing Capacitor plugin repository so apps using CapApp-SPM can consume it after CocoaPods Trunk goes read-only…
Skill by Cap-go
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/cap-go-capacitor-plugin-spm-support
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 4
capacitorjs.com· found in codecodeload.github.com· found in install commandgithub.com· found in codeswift.org· found in code
Files it touches
~/.claude/skills/capacitor-plugin-spm-support
What's inside
- Skill name
capacitor-plugin-spm-support- Description
- Adds Swift Package Manager support to an existing Capacitor plugin repository so apps using CapApp-SPM can consume it after CocoaPods Trunk goes read-only (expected December 2, 2026). Covers root Package.swift naming rules the Capacitor CLI depends on, CAPBridgedPlugin conversion (identifier, jsName, pluginMethods), removing the ObjC CAP_PLUGIN bridge (.m/.h), Sources/Tests layout, podspec and package.json files updates, third-party pod to SPM dependency mapping, resources/PrivacyInfo.xcprivacy, binary xcframeworks, and Capacitor 9 removal of the unconditional Cordova product. Use when app sync warns "<plugin> does not have a Package.swift" for a plugin you own, or "plugin is not implemented on ios" only in SPM apps. Do not use for migrating an app project (use cocoapods-to-spm), version bumps of plugins (use capacitor-plugin-upgrades / capacitor-plugin-upgrade-v8-to-v9), or choosing plugins (use capacitor-plugins).
- License
- MIT
- Instructions
- 98 lines in SKILL.md · view on GitHub
Files (3)
- SKILL.md
- metadata.json
- package-swift-templates.md · references/
SKILL.md (first lines)
# Add Swift Package Manager Support to a Capacitor Plugin
Make a plugin installable in SPM-based Capacitor apps while keeping its podspec for CocoaPods apps.
## When to Use
TRIGGER when:
- A plugin repo has `ios/Plugin/*.swift` + `*.m`/`*.h` with `CAP_PLUGIN(...)` and no root `Package.swift`.
- An app's `npx cap sync ios` prints `<plugin id> does not have a Package.swift` for a plugin the user maintains.
- A plugin works with CocoaPods but JS gets `"X" plugin is not implemented on ios` in SPM apps.
- Preparing a plugin for Capacitor 9 / CocoaPods Trunk read-only.
Do not use:
- App-side CocoaPods removal -> `cocoapods-to-spm`.
- Capacitor major bumps of a plugin -> `capacitor-plugin-upgrades`, `capacitor-plugin-upgrade-v8-to-v9`.
- Android-only plugin work, or non-Capacitor (pure Cordova, React Native) plugins.
## Rules the CLI Enforces (non-obvious)
- `Package.swift` must be at the **npm package root** (next to `package.json`), not under `ios/`. The app CLI only checks `<plugin root>/Package.swift`.
- The CLI references the plugin in the app's `CapApp-SPM/Package.swift` as `.package(name: "<Name>", path: ...)` and `.product(name: "<Name>", package: "<Name>")`, where `<Name>` is derived from the npm name: drop `@`, turn `/` and `-` into word breaks, PascalCase. `@capgo/capacitor-updater` -> `CapgoCapacitorUpdater`, `@acme/capacitor-foo-bar` -> `AcmeCapacitorFooBar`. The `Package(name:)` **and** the `.library(name:)` product must both equal `<Name>`, or app builds fail to resolve the product.
- Runtime registration uses `ios/App/App/capacitor.config.json` -> `packageClassList`, filled by scanning the plugin's iOS sources (`capacitor.ios.src` in package.json, default `ios`) for `@objc(ClassName)`. Keep `@objc(<Class>Plugin)` on the class; without it the plugin is never registered.
- The `capacitor-swift-pm` dependency must use `from: "<major>.0.0"`. If the major differs from the app's Capacitor, app sync rewrites it in `node_modules` and warns `<id> is built for Capacitor <N>, it might cause issues`.
- Capacitor 9: depend only on `.product(name: "Capacitor", package: "capacitor-swift-pm")`. Remove the unconditional `Cordova` product; it is only present in apps that install a Cordova plugin. Keep it on Capacitor 8 only if your code imports Cordova.
## Procedure
### 1. Inspect
Read `package.json` (name, `files`, `capacitor.ios.src`, scripts), the `.podspec` (`s.name`, `s.ios.deployment_target`, `s.dependency`, `s.resources`, `s.vendored_frameworks`), every file in `ios/`, and the `CAP_PLUGIN(...)` macro in the `.m` file.
Record: SPM `<Name>` (rule above), class name, `jsName`, every `CAP_PLUGIN_METHOD(name, returnType)`, iOS deployment target, third-party pods, resources, vendored frameworks, ObjC/C sources other than the bridge.
Check each third-party pod has an official SPM package. Report any that do not before editing; ask whether to drop, vendor as `.xcframework`, or keep the plugin CocoaPods-only.
### 2. Fast path: converter
If the iOS code is Swift-only apart from the `[Name]Plugin.m` / `.h` bridge, the official converter does most of the work (adds `CAPBridgedPlugin`, creates `Package.swift`, moves code to `ios/Sources` and `ios/Tests`, removes `Plugin.xcodeproj`/`xcworkspace`/`Podfile`, updates podspec `source_files`, `files`, and `verify:ios`): https://github.com/ionic-team/capacitor-plugin-converter. Review its diff against the rules above, especially the package/product name.
### 3. Manual conversion
1. Move sources: `ios/Plugin/` -> `ios/Sources/<ClassName>/`, tests -> `ios/Tests/<ClassName>Tests/`.
2. Convert the class (keep method names and return types exactly as in the `.m` macro):
```swift
import Capacitor
@objc(FooPlugin)
public class FooPlugin: CAPPlugin, CAPBridgedPlugin {
public let identifier = "FooPlugin" // first CAP_PLUGIN argument
public let jsName = "Foo" // second CAP_PLUGIN argument (registerPlugin name)
public let pluginMethods: [CAPPluginMethod] = [
CAPPluginMethod(name: "doThing", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "watch", returnType: CAPPluginReturnCallback),
CAPPluginMethod(name: "fireAndForget", returnType: CAPPluginReturnNone)
]
@objc func doThing(_ call: CAPPluginCall) { call.resolve() }
}
```
3. Delete `FooPlugin.m` and `FooPlugin.h` (the `CAP_PLUGIN` bridge) and stale `Plugin.xcodeproj`, `Plugin.xcworkspace`, `Podfile`, `Info.plist` files under `ios/`.
4. Add root `Package.swift`. Template and variants (resources, binary targets, third-party packages, mixed ObjC) in `references/package-swift-templates.md`.
5. Update the podspec: `s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'`, keep `s.dependency 'Capacitor'`, and mirror deployment target and resources.
6. Update `package.json`:
- `files`: add `ios/Sources/`, `Package.swift`; keep the `.podspec`; remove old `ios/Plugin/`.
- `verify:ios`: `xcodebuild -scheme <Name> -destination generic/platform=iOS`.
## Verification
```bash
# Package resolves and builds standalone (from plugin root)
swift package describe >/dev/null && echo "manifest ok"
xcodebuild -scheme <Name> -destination generic/platform=iOS build
# Published tarball contains the manifest and sources
npm pack --dry-run 2>&1 | grep -E 'Package.swift|ios/Sources'
# No leftover ObjC bridge
grep -rn "CAP_PLUGIN(" ios/ && echo "LEFTOVER BRIDGE"
```
Then in an SPM example/test app (directory with `capacitor.config.*`): install the plugin (`npm install ../path` or a packed tarball), run `npx cap sync ios`, confirm no `does not have a Package.swift` warning, confirm `<Name>` appears in `ios/App/CapApp-SPM/Package.swift` and the class appears in `ios/App/App/capacitor.config.json` `packageClassList`, build, and call one method from JS. Also run `pod lib lint` (or a CocoaPods example app) if the podspec is still published.
## Error Handling
| Error | Fix |
|---|---|
| `product '<Name>' required by package 'capapp-spm' target 'CapApp-SPM' not found in package '<Name>'` | `Package(name:)` / `.library(name:)` do not match the CLI-derived `<Name>`. |
| `"Foo" plugin is not implemented on ios` | Missing `@objc(FooPlugin)`, wrong `jsName`, or class not in `packageClassList`; re-sync after fixing. |
| `"Foo.bar()" is not implemented on ios` | Method missing from `pluginMethods` or not marked `@objc`. |
| `No such module 'Capacitor'` building the package | Missing `capacitor-swift-pm` dependency or wrong product name. |
| `public headers ("include") directory path for 'X' is invalid or not contained in the target` | Mixed ObjC target without `publicHeadersPath`; split ObjC into its own target (see reference). |
| `<id> is built for Capacitor <N>, it might cause issues` (in app) | Bump `capacitor-swift-pm` `from:` to the app's major. |
| `Cordova` product missing (Capacitor 9 app) | Remove the `Cordova` product dependency. |
| Resource not found at runtime | Declare `resources:` and load via `Bundle.module`, not `Bundle.main`. |
## References
Only load when the topic is in play:
- `references/package-swift-templates.md`: base manifest, resources and privacy manifest, third-party SPM dependencies, binary `.xcframework`, mixed Swift/ObjC targets, Capacitor 8 vs 9 dependency blocks.From Cap-go/capgo-skills, MIT.
More from Cap-go/capgo-skills
- 0.674score
capacitor-offline-first
Cap-go
Designs and implements offline-first data in Capacitor apps - local SQLite source of truth with @capgo/capacitor-fast-sql (`FastSQL.connect`…
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-accessibility
Cap-go
Makes Capacitor apps work with VoiceOver, TalkBack, Dynamic Type / Android font scale, Switch Control, hardware keyboards, Reduce Motion and Increase Contrast.
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-mcp
Cap-go
Connect AI agents (Claude Code, Claude Desktop, Cursor, VS Code, Cline, Codex) to Capacitor and Ionic tooling over Model Context Protocol.
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-deep-linking
Cap-go
Implements and debugs deep links in Capacitor apps - custom URL schemes, iOS Universal Links (apple-app-site-association, Associated Domains entitlement)…
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-splash-screen
Cap-go
Configures and debugs launch splash screens in Capacitor apps with @capacitor/splash-screen and @capacitor/assets - `launchAutoHide`, `SplashScreen.hide()`…
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
cocoapods-to-spm
Cap-go
Migrates an existing Capacitor iOS app from CocoaPods to Swift Package Manager (SPM) before CocoaPods Trunk goes read-only (expected December 2, 2026).
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-testing
Cap-go
Testing guide for Capacitor apps and plugins.
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-best-practices
Cap-go
Review and set up Capacitor apps against current best practices (Capacitor 8.5 stable, 9 alpha via `@next`).
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-plugins
Cap-go
Pick, install, and wire up Capacitor plugins for native features (camera, filesystem, geolocation, biometrics, in-app purchases, social login, SQLite…
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-app-intents
Cap-go
Exposes Capacitor app features to Siri, Shortcuts, Spotlight, the Action button, Apple Intelligence, widgets and controls with native App Intents in…
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-push-notifications
Cap-go
Sets up and debugs remote push in Capacitor apps with @capacitor/push-notifications (FCM on Android, APNs on iOS), or Capgo alternatives…
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-performance
Cap-go
Diagnoses and fixes performance problems specific to Capacitor apps - slow cold start or long splash, white screen after camera/backgrounding (WKWebView…
SkillAFreshness: A★ 73Claude Code +9
Signals
- Stars
- 73
- Forks
- 3
- Open issues
- 0
- Last commit (this folder)
- Oct 11, 2026 (17 days ago)
- Last release
- Oct 11, 2026 (17 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/Cap-go/capgo-skills
- Website
- capgo.app
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from Cap-go
- 0.674score
capacitor-best-practices
Cap-go
Review and set up Capacitor apps against current best practices (Capacitor 8.5 stable, 9 alpha via `@next`).
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-plugins
Cap-go
Pick, install, and wire up Capacitor plugins for native features (camera, filesystem, geolocation, biometrics, in-app purchases, social login, SQLite…
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-testing
Cap-go
Testing guide for Capacitor apps and plugins.
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
cocoapods-to-spm
Cap-go
Migrates an existing Capacitor iOS app from CocoaPods to Swift Package Manager (SPM) before CocoaPods Trunk goes read-only (expected December 2, 2026).
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-mcp
Cap-go
Connect AI agents (Claude Code, Claude Desktop, Cursor, VS Code, Cline, Codex) to Capacitor and Ionic tooling over Model Context Protocol.
SkillAFreshness: A★ 73Claude Code +9 - 0.674score
capacitor-app-intents
Cap-go
Exposes Capacitor app features to Siri, Shortcuts, Spotlight, the Action button, Apple Intelligence, widgets and controls with native App Intents in…
SkillAFreshness: A★ 73Claude Code +9
Cite this page
capacitor-plugin-spm-support skill. Agent Mart. https://agentmart.dev/skills/cap-go-capacitor-plugin-spm-support (last updated 2026-10-24)