---
description: Learn how to add Swift Package Manager support to your Capacitor plugin with three migration approaches, from automated tools to AI-powered agents.
title: How to Migrate a Capacitor Plugin to SPM - Capawesome
image: https://capawesome.io/docs/assets/images/social/blog/how-to-migrate-a-capacitor-plugin-to-spm.png
---

[ Skip to content](#how-to-migrate-a-capacitor-plugin-to-swift-package-manager) 

[ 🔐 Introducing the **Capacitor Vault** plugin — store secrets behind biometrics or a device passcode.](/blog/announcing-the-capacitor-vault-plugin/) 

* [  SDKs ](/docs/sdks/)
* [  Formbricks ](/docs/sdks/capacitor/formbricks/)
* [  Geocoder ](/docs/sdks/capacitor/geocoder/)
* [  Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [  Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [  libSQL ](/docs/sdks/capacitor/libsql/)
* [  Live Update ](/docs/sdks/capacitor/live-update/)
* [  Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [  Media Session ](/docs/sdks/capacitor/media-session/)
* [  ML Kit ](/docs/sdks/capacitor/mlkit/)
* [  Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [  NFC ](/docs/sdks/capacitor/nfc/)
* [  OAuth ](/docs/sdks/capacitor/oauth/)
* [  Pedometer ](/docs/sdks/capacitor/pedometer/)
* [  Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [  PostHog ](/docs/sdks/capacitor/posthog/)
* [  Printer ](/docs/sdks/capacitor/printer/)
* [  Purchases ](/docs/sdks/capacitor/purchases/)
* [  RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [  Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [  Screenshot ](/docs/sdks/capacitor/screenshot/)
* [  Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [  Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [  Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [  Share Target ](/docs/sdks/capacitor/share-target/)
* [  Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [  SQLite ](/docs/sdks/capacitor/sqlite/)
* [  Superwall ](/docs/sdks/capacitor/superwall/)
* [  Torch ](/docs/sdks/capacitor/torch/)
* [  Vault ](/docs/sdks/capacitor/vault/)
* [  Wifi ](/docs/sdks/capacitor/wifi/)
* [  Zip ](/docs/sdks/capacitor/zip/)
* [  Cordova ](/docs/sdks/cordova/)
* [  Cloud ](/docs/cloud/)
* [  Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [  Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [  FAQ ](/docs/cloud/live-updates/faq/)
* [  Native Builds ](/docs/cloud/native-builds/)
* [  Set Up Environments ](/docs/cloud/native-builds/environments/)
* [  Overwrite Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [  Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [  Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [  Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [  Use pnpm or Yarn ](/docs/cloud/native-builds/package-managers/)
* [  Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [  Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [  Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [  Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [  Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [  Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [  Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [  FAQ ](/docs/cloud/native-builds/faq/)
* [  App Store Publishing ](/docs/cloud/app-store-publishing/)
* [  Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [  Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [  Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [  FAQ ](/docs/cloud/app-store-publishing/faq/)
* [  Automations ](/docs/cloud/automations/)
* [  Reference ](/docs/cloud/automations/reference/)
* [  Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [  FAQ ](/docs/cloud/automations/faq/)
* [  Assist ](/docs/cloud/assist/)
* [  CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [  Webhooks ](/docs/cloud/webhooks/)
* [  Integrations ](/docs/cloud/integrations/)
* Account
* [  Organization ](/docs/cloud/organizations/)
* [  Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [  Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [  Billing ](/docs/cloud/organizations/billing/)
* [  License Keys ](/docs/cloud/license-keys/)
* [  AI ](/docs/ai/)
* [  Insiders ](/docs/insiders/)
* [  Billing & Plans ](/docs/insiders/billing-and-plans/)
* [  FAQ ](/docs/insiders/faq/)
* [  License ](https://capawesome.io/legal/eula/)
* [  Support ](/docs/support/)
* [  Contributing ](/docs/contributing/)
* Contributing code
* [  Code of Conduct ](/docs/contributing/code-of-conduct/)
* [  Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [  Blog ](/blog/)
* Categories

* [  Migration Options ](#migration-options)
* [  Try Capawesome Cloud ](#try-capawesome-cloud)
* [  Conclusion ](#conclusion)

# How to Migrate a Capacitor Plugin to Swift Package Manager[¶](#how-to-migrate-a-capacitor-plugin-to-swift-package-manager "Permanent link")

Capacitor 8 made Swift Package Manager (SPM) the default dependency manager for iOS. If you maintain a Capacitor plugin that still relies on CocoaPods and Objective-C bridge files, your plugin won't work out of the box in SPM-based projects. This post walks you through what needs to change and three ways to get it done.

[ ![Build and deploy your Capacitor app with Capawesome Cloud](../../assets/external/cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.69628c3f.png) ](https://cloud.capawesome.io/) 

## What Changes Are Needed[¶](#what-changes-are-needed "Permanent link")

The migration from CocoaPods to SPM touches a handful of files. Here's what's involved at a high level:

### Add a Package.swift Manifest[¶](#add-a-packageswift-manifest "Permanent link")

SPM needs a `Package.swift` at the root of your plugin repository. This file defines the package name, supported platforms, dependencies, and targets. A typical setup points the main target at `ios/Plugin` and the test target at `ios/PluginTests`:

`[](#%5F%5Fcodelineno-0-1)// swift-tools-version: 5.9
[](#%5F%5Fcodelineno-0-2)import PackageDescription
[](#%5F%5Fcodelineno-0-3)
[](#%5F%5Fcodelineno-0-4)let package = Package(
[](#%5F%5Fcodelineno-0-5)    name: "MyCapacitorPlugin",
[](#%5F%5Fcodelineno-0-6)    platforms: [.iOS(.v15)],
[](#%5F%5Fcodelineno-0-7)    products: [
[](#%5F%5Fcodelineno-0-8)        .library(
[](#%5F%5Fcodelineno-0-9)            name: "MyCapacitorPlugin",
[](#%5F%5Fcodelineno-0-10)            targets: ["MyCapacitorPluginTarget"])
[](#%5F%5Fcodelineno-0-11)    ],
[](#%5F%5Fcodelineno-0-12)    dependencies: [
[](#%5F%5Fcodelineno-0-13)        .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", branch: "8.0.0")
[](#%5F%5Fcodelineno-0-14)    ],
[](#%5F%5Fcodelineno-0-15)    targets: [
[](#%5F%5Fcodelineno-0-16)        .target(
[](#%5F%5Fcodelineno-0-17)            name: "MyCapacitorPluginTarget",
[](#%5F%5Fcodelineno-0-18)            dependencies: [
[](#%5F%5Fcodelineno-0-19)                .product(name: "Capacitor", package: "capacitor-swift-pm"),
[](#%5F%5Fcodelineno-0-20)                .product(name: "Cordova", package: "capacitor-swift-pm")
[](#%5F%5Fcodelineno-0-21)            ],
[](#%5F%5Fcodelineno-0-22)            path: "ios/Plugin"),
[](#%5F%5Fcodelineno-0-23)        .testTarget(
[](#%5F%5Fcodelineno-0-24)            name: "MyCapacitorPluginTests",
[](#%5F%5Fcodelineno-0-25)            dependencies: ["MyCapacitorPluginTarget"],
[](#%5F%5Fcodelineno-0-26)            path: "ios/PluginTests")
[](#%5F%5Fcodelineno-0-27)    ]
[](#%5F%5Fcodelineno-0-28))
`

If your plugin depends on third-party libraries (like a database driver or a networking library), add them to the `dependencies` array and reference them in your target's dependencies.

### Replace Objective-C Bridge Files with CAPBridgedPlugin[¶](#replace-objective-c-bridge-files-with-capbridgedplugin "Permanent link")

Older Capacitor plugins use Objective-C files (typically `Plugin.h` and `Plugin.m`) containing the `CAP_PLUGIN` macro to register plugin methods. SPM doesn't support mixing Objective-C and Swift in the same target, so these files need to go.

Instead, your plugin's main Swift class should conform to the `CAPBridgedPlugin` protocol. This means adding three properties: `identifier`, `jsName`, and `pluginMethods`:

`[](#%5F%5Fcodelineno-1-1)import Capacitor
[](#%5F%5Fcodelineno-1-2)
[](#%5F%5Fcodelineno-1-3)@objc(MyPlugin)
[](#%5F%5Fcodelineno-1-4)public class MyPlugin: CAPPlugin, CAPBridgedPlugin {
[](#%5F%5Fcodelineno-1-5)    public let identifier = "MyPlugin"
[](#%5F%5Fcodelineno-1-6)    public let jsName = "MyPlugin"
[](#%5F%5Fcodelineno-1-7)    public let pluginMethods: [CAPPluginMethod] = [
[](#%5F%5Fcodelineno-1-8)        CAPPluginMethod(name: "echo", returnType: CAPPluginReturnPromise),
[](#%5F%5Fcodelineno-1-9)        CAPPluginMethod(name: "getData", returnType: CAPPluginReturnPromise)
[](#%5F%5Fcodelineno-1-10)    ]
[](#%5F%5Fcodelineno-1-11)
[](#%5F%5Fcodelineno-1-12)    // ... plugin implementation
[](#%5F%5Fcodelineno-1-13)}
`

The `pluginMethods` array replaces the `CAP_PLUGIN_METHOD` entries from the old `.m` file. Make sure every method your plugin exposes to JavaScript is listed here — any omission means that method won't be callable at runtime.

After updating the Swift file, delete the `.h` and `.m` bridge files.

### Update .gitignore[¶](#update-gitignore "Permanent link")

Add SPM-related entries to your `.gitignore` to keep build artifacts out of version control:

`[](#%5F%5Fcodelineno-2-1)Package.resolved
[](#%5F%5Fcodelineno-2-2)/.build
[](#%5F%5Fcodelineno-2-3)/Packages
[](#%5F%5Fcodelineno-2-4).swiftpm/configuration/registries.json
[](#%5F%5Fcodelineno-2-5).swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
[](#%5F%5Fcodelineno-2-6).netrc
`

### Clean Up the Xcode Project File[¶](#clean-up-the-xcode-project-file "Permanent link")

The `ios/Plugin.xcodeproj/project.pbxproj` file still references the deleted Objective-C files. Remove any lines that reference your old `.h` and `.m` files from the `PBXBuildFile`, `PBXFileReference`, `PBXGroup`, `PBXHeadersBuildPhase`, and `PBXSourcesBuildPhase` sections. This step is tedious to do by hand, which is one reason the automated tools described below are helpful.

### Update package.json[¶](#update-packagejson "Permanent link")

Add `Package.swift` to the `files` array in your `package.json` so it gets included when you publish to npm:

`[](#%5F%5Fcodelineno-3-1){
[](#%5F%5Fcodelineno-3-2)  "files": [
[](#%5F%5Fcodelineno-3-3)    "dist/",
[](#%5F%5Fcodelineno-3-4)    "ios/Plugin/",
[](#%5F%5Fcodelineno-3-5)    "android/",
[](#%5F%5Fcodelineno-3-6)    "Package.swift"
[](#%5F%5Fcodelineno-3-7)  ]
[](#%5F%5Fcodelineno-3-8)}
`

You can also add a convenience script for resolving SPM dependencies locally:

`[](#%5F%5Fcodelineno-4-1){
[](#%5F%5Fcodelineno-4-2)  "scripts": {
[](#%5F%5Fcodelineno-4-3)    "ios:spm:install": "swift package resolve"
[](#%5F%5Fcodelineno-4-4)  }
[](#%5F%5Fcodelineno-4-5)}
`

## Migration Options[¶](#migration-options "Permanent link")

You don't have to do all of this manually. Here are three approaches, depending on your situation.

### Option 1: Capacitor Plugin Converter[¶](#option-1-capacitor-plugin-converter "Permanent link")

The Ionic team maintains [capacitor-plugin-converter](https://github.com/ionic-team/capacitor-plugin-converter), a CLI tool called `cap2spm` that automates the conversion. It reads your `Plugin.m` and `Plugin.h` files, modifies your `Plugin.swift` to add `CAPBridgedPlugin` conformance, and generates a `Package.swift`.

Install it via curl:

`[](#%5F%5Fcodelineno-5-1)curl -OL https://github.com/ionic-team/capacitor-plugin-converter/releases/latest/download/cap2spm.zip
`

Then run it against your plugin directory:

`[](#%5F%5Fcodelineno-6-1)./cap2spm /path/to/your/plugin
`

A few things to keep in mind:

* The tool is still under heavy development. It works for most cases, but make sure you have a clean commit before running it.
* The binary is currently unsigned. If you download it from a browser on macOS, you'll need to remove the quarantine attribute first:  
`[](#%5F%5Fcodelineno-7-1)xattr -d com.apple.quarantine ./cap2spm  
`

### Option 2: Capawesome Skills[¶](#option-2-capawesome-skills "Permanent link")

[Capawesome Skills](https://github.com/capawesome-team/skills) is a collection of AI-powered agent skills for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) and other AI coding agents. It includes a dedicated `capacitor-plugin-spm-support` skill that guides the agent through the full migration: creating `Package.swift`, replacing Objective-C bridge files, updating `.gitignore`, cleaning up the Xcode project file, and updating `package.json`.

Install the skills:

`[](#%5F%5Fcodelineno-8-1)npx skills add capawesome-team/skills
`

Then prompt your AI agent:

`[](#%5F%5Fcodelineno-9-1)Add Swift Package Manager support to my Capacitor plugin.
`

The agent will walk through each step, adapting to your plugin's specific setup and dependencies.

### Option 3: Create a New Plugin from Scratch[¶](#option-3-create-a-new-plugin-from-scratch "Permanent link")

If your plugin is relatively simple or you're planning a rewrite anyway, you can scaffold a fresh plugin using [create-capacitor-plugin](https://github.com/ionic-team/create-capacitor-plugin):

`[](#%5F%5Fcodelineno-10-1)npm init @capacitor/plugin my-plugin
`

New plugins created with this tool already include full SPM support out of the box. Once the scaffold is ready, migrate your existing implementation code into the new project structure. This approach works best for smaller plugins where copying the implementation is less effort than modifying the existing project files.

## Try Capawesome Cloud[¶](#try-capawesome-cloud "Permanent link")

If you're building Capacitor apps or plugins, [Capawesome Cloud](https://cloud.capawesome.io/) can help you ship faster with cloud-based native builds, over-the-air updates, and automated app store publishing.

[Try Capawesome Cloud Free](https://cloud.capawesome.io)

## Conclusion[¶](#conclusion "Permanent link")

Adding SPM support to your Capacitor plugin is becoming essential as the iOS ecosystem moves away from CocoaPods. The changes are well-defined — a `Package.swift` manifest, `CAPBridgedPlugin` conformance, and some cleanup — and you have several tools to help automate the process. Whether you prefer a CLI tool, an AI agent, or a fresh scaffold, you can get your plugin ready for SPM-based projects without too much effort.

If you still need CocoaPods for your app project, check out [How to Use CocoaPods Instead of SPM with Capacitor](/blog/how-to-use-cocoapods-with-capacitor/) for guidance on when and how to use it as a fallback.

If you have questions, feel free to join the [Capawesome Discord server](https://discord.gg/VCXxSVjefW). To stay up to date with the latest news, subscribe to the [Capawesome newsletter](https://cloud.capawesome.io/newsletter).

May 7, 2026 

 Back to top 