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.

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.

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.
  • Testing
  • Tests

Copy link

changeset-bot bot commented Sep 5, 2025

🦋 Changeset detected

Latest commit: b161d93

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).


## Examples

See the [`demos/example-capacitor/`](https://github.com/journeyapps/powersync-react-native-sdk/blob/capacitor-sdk/demos/example-capacitor/README.md#L1) directory for a working example.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

TODO: Need to update this before merging


export const AppSchema = new Schema({
customers
lists: customers
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

TODO: Need to revert this. This makes testing easier for me :D

@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
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.

3 participants