Skip to content

Conversation

@stevensJourney
Copy link
Collaborator

@stevensJourney stevensJourney commented Sep 5, 2025

Overview

Theoretically, one should be able to use the PowerSync Web SDK in Capacitor Webviews. Recent support items have shown that while this works in practice, the experience is not very stable in some circumstances.

This uses https://github.com/capacitor-community/sqlite as the SQLite driver for PowerSync - with the main aim to target iOS and Android platforms (only iOS has been tested so far).

The Capacitor Community SQLite package currently poses some challenges for PowerSync's use-case:

  • Extension loading is not supported. There are APIs for loading an extension, but attempting to use those on iOS results in
    Unhandled Promise Rejection: Error: "CapacitorSQLite.loadExtension()" is not implemented on ios
  • Update hooks don't seem to be implemented
  • The methods for SQL execution are split between execute and query operations. The PowerSync JS clients currently allow running queries which return results from the execute methods.

We can work around most of these limitations.

Extension Loading
This PR adds a Capacitor Plugin which includes the PowerSync Rust core into a project. We can then register a static SQLite auto extension. We use the low level C APIs for this.
We currently statically register the PowerSync core extension on iOS platforms.
Android now supports dynamically loading extensions.

Update Hooks
We register an update hook implementation internally via our Rust Core implementation.

Query execution differences
This is documented as a limitation of the API for Android.

Changes In This PR

  • The example-capacitor demo is upgraded to Capacitor v7.
  • A new @powersync/capacitor package is introduced. The scaffolding for this was taken from a Capacitor plugin template
    • The template uses an internal example-app to verify iOS compilation

TODOS

  • The Example Capacitor currently uses this plugin by using a CapacitorSQLiteAdapter for the DBAdapter provided to the PowerSync Web SDK. While this does work, it seems messy. We should probably introduce a dedicated Capacitor PowerSyncDatabase constructor.
  • Android support
  • Performance: Current benchmarks show terrible results. Executing 1000 individual inserts takes over 30 seconds.

Future Work:
Unit tests will be added after the initial release.

@changeset-bot
Copy link

changeset-bot bot commented Sep 5, 2025

🦋 Changeset detected

Latest commit: fd25e44

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

@simolus3
Copy link
Contributor

simolus3 commented Sep 5, 2025

A future version of the PowerSync core could support internal table update reporting mechagnisms.

The future is now! With version 0.4.5 of the core extension, you can:

  1. When the write connection is initialized, run SELECT powersync_update_hooks('install') (Kotlin for reference).
  2. After a transaction may have completed (you can likely put this at the end of writeLock), call SELECT powersync_update_hooks('get') as r. This will return a json array of all tables with a commited write since the last get invocation (Kotlin for reference).

@stevensJourney
Copy link
Collaborator Author

stevensJourney commented Sep 22, 2025

Some basic benchmark comparisons were ran on an Android Emulator + iPhone Simulator.
A basic test for executing 1000 INSERT statements (1000 .execute(...) calls) was conducted. The time take for the INSERT operations to complete was recorded.

const now = performance.now();
for (let i = 0; i < 1_000; i++) {
  await powerSync.execute('INSERT INTO customers (id, name) VALUES (uuid(), ?)', [`Customer`]);
}
const end = performance.now();
Platform Capacitor SQLite (ms) AccessHandle OPFS (ms) COOP OPFS (ms) IndexedDB (ms)
iOS 864 895 982 4,948
Android 3,129 3,931 3,431 10,890

For general mobile comparisons, see https://www.powersync.com/blog/react-native-database-performance-comparison

@stevensJourney stevensJourney changed the title [POC] Capacitor Community SQLite Capacitor Community SQLite Sep 22, 2025
@stevensJourney stevensJourney marked this pull request as ready for review October 30, 2025 16:18
Chriztiaan
Chriztiaan previously approved these changes Oct 31, 2025
simolus3
simolus3 previously approved these changes Oct 31, 2025
Copy link
Contributor

@simolus3 simolus3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool to see powersync_update_hooks in action :)

@stevensJourney stevensJourney dismissed stale reviews from simolus3 and Chriztiaan via fd25e44 October 31, 2025 14:08
@stevensJourney stevensJourney merged commit a6e3db4 into main Oct 31, 2025
9 of 11 checks passed
@stevensJourney stevensJourney deleted the capacitor-sdk branch October 31, 2025 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants