Skip to content

feat: Capacitor SPM#973

Merged
stevensJourney merged 8 commits into
mainfrom
capacitor
May 25, 2026
Merged

feat: Capacitor SPM#973
stevensJourney merged 8 commits into
mainfrom
capacitor

Conversation

@stevensJourney
Copy link
Copy Markdown
Collaborator

@stevensJourney stevensJourney commented May 21, 2026

Overview

Capacitor 6 added support for SPM in iOS builds. The default package manager was still set to Cocoapods till version 8, where SPM became the default.

The PowerSync Capacitor SDK exports a Capacitor plugin which registers the PowerSync SQLite core extension as a SQLite auto extension using the C sqlite3_auto_extension function. This method allows us to register the PowerSync core extension behind @capacitor-community/sqlite's back - since it does not provide a direct method of loading SQLite extensions.

Our Capacitor plugin currently only supports a Cocoapod integration - it thus only works on Capacitor iOS projects which use Cocoapods as the package manager.

This PR adds support for SPM to our PowerSync Capacitor plugin. This causes a chain of requirements and events to unfold.

  • Capacitor Community SQLite supports SPM since version 8.1.0. In order to use this version, one needs to match its capacitor requirement of Capacitor 8
  • We then need to bump our minimum Capacitor version supported to version 8 if SPM is required.
  • There doesn't seem to be a nice way to support both Capacitor 7 (and below) and Capacitor 8 at the same time, so we effectively will drop support for older versions.

Details

PowerSync Capacitor

The PowerSync Capacitor plugin's Capacitor dependencies have been bumped to version 8. A Package.swift file has been added as the entry point for SPM. Some of the low level C header imports have been updated in order to be compatible with a SPM build environment.

Example Capacitor

The example-capacitor demo has been upgraded to version 8 by following the guide. I verified both Android and iOS were functioning normally.

Internal Testing Example

The norm for Capacitor plugins is to have a small example-app inside the package which is used to run compilation tasks during development, e.g. the verify:ios script which ensures the plugin compiles with XCode. I've updated this to Capacitor 8 as well.

Minimum Targets

As mentioned in the Capacitor docs. Upgrading to Capacitor 8 raises the minimum iOS to iOS 15.0. Android's minimum is minSdkVersion = 24

Product Visibility

I've added the Product Visibility label since this drops support for older Capacitor versions.

TODOs

  • Smoke test with Cocoapods example app

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 21, 2026

🦋 Changeset detected

Latest commit: 84381ab

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@powersync/capacitor Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@stevensJourney stevensJourney added the Product Visibility This requires documentation changes and or announcing. label May 21, 2026
@stevensJourney stevensJourney marked this pull request as ready for review May 25, 2026 07:03
@Chriztiaan
Copy link
Copy Markdown
Contributor

Out of curiosity, how are SPM dev releases kicked off from the Capacitor package? And have we tested an SPM based dev release?

@stevensJourney
Copy link
Copy Markdown
Collaborator Author

Out of curiosity, how are SPM dev releases kicked off from the Capacitor package? And have we tested an SPM based dev release?

That's a good question... We don't actually publish a Swift repo for SPM usage. This adds support with Capacitor's SPM integration. Capacitor will configure an application to use SPM and link the relevant plugins (like our Capacitor plugin). The linking process usually involves linking the Package.swift file, provided by installing the @powersync/capacitor NPM package to the application's SPM dependencies. An example of this is present in the example-capacitor demo.

demos/example-capacitor/ios/App/CapApp-SPM/Package.swift

// DO NOT MODIFY THIS FILE - managed by Capacitor CLI commands
let package = Package(
    name: "CapApp-SPM",
    platforms: [.iOS(.v15)],
    products: [
        .library(
            name: "CapApp-SPM",
            targets: ["CapApp-SPM"])
    ],
    dependencies: [
        .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", exact: "8.3.4"),
        .package(name: "CapacitorCommunitySqlite", path: "../../../node_modules/.pnpm/@capacitor-community+sqlite@8.1.0_@capacitor+core@8.3.4/node_modules/@capacitor-community/sqlite"),
        .package(name: "CapacitorSplashScreen", path: "../../../node_modules/.pnpm/@capacitor+splash-screen@8.0.1_@capacitor+core@8.3.4/node_modules/@capacitor/splash-screen"),
        .package(name: "PowersyncCapacitor", path: "../../../node_modules/@powersync/capacitor")
    ],

I haven't tested an explicit dev release, but I have confirmed that our package.json includes these SPM files, so they should be published. I will do a smoke test.

@Chriztiaan
Copy link
Copy Markdown
Contributor

Out of curiosity, how are SPM dev releases kicked off from the Capacitor package? And have we tested an SPM based dev release?

That's a good question... We don't actually publish a Swift repo for SPM usage. This adds support with Capacitor's SPM integration. Capacitor will configure an application to use SPM and link the relevant plugins (like our Capacitor plugin). The linking process usually involves linking the Package.swift file, provided by installing the @powersync/capacitor NPM package to the application's SPM dependencies. An example of this is present in the example-capacitor demo.

demos/example-capacitor/ios/App/CapApp-SPM/Package.swift

// DO NOT MODIFY THIS FILE - managed by Capacitor CLI commands
let package = Package(
    name: "CapApp-SPM",
    platforms: [.iOS(.v15)],
    products: [
        .library(
            name: "CapApp-SPM",
            targets: ["CapApp-SPM"])
    ],
    dependencies: [
        .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", exact: "8.3.4"),
        .package(name: "CapacitorCommunitySqlite", path: "../../../node_modules/.pnpm/@capacitor-community+sqlite@8.1.0_@capacitor+core@8.3.4/node_modules/@capacitor-community/sqlite"),
        .package(name: "CapacitorSplashScreen", path: "../../../node_modules/.pnpm/@capacitor+splash-screen@8.0.1_@capacitor+core@8.3.4/node_modules/@capacitor/splash-screen"),
        .package(name: "PowersyncCapacitor", path: "../../../node_modules/@powersync/capacitor")
    ],

I haven't tested an explicit dev release, but I have confirmed that our package.json includes these SPM files, so they should be published. I will do a smoke test.

I see where my confusion stemmed from. That's neat! Thanks.

@stevensJourney
Copy link
Copy Markdown
Collaborator Author

I verified that using a dev version of these changes in our example-capacitor demo - worked as expected :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Product Visibility This requires documentation changes and or announcing.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants