Skip to content

Document custom SQLite artifact pairs and connection probes - #688

Open
akpor-kofi wants to merge 1 commit into
powersync-ja:mainfrom
akpor-kofi:docs/custom-sqlite-artifact-pairs
Open

akpor-kofi wants to merge 1 commit into
powersync-ja:mainfrom
akpor-kofi:docs/custom-sqlite-artifact-pairs

Conversation

@akpor-kofi

Copy link
Copy Markdown

Summary

Expand the existing SQLite extensions page with the build/deployment requirements for custom wa-sqlite modules: pin the toolchain, preserve PowerSync core, ship matching JavaScript/WASM, rebuild prebundled database workers, version assets, and probe the actual database connection. Add a runnable decimal probe and clarify native rebuild and SQLCipher initialization requirements.

This documentation describes the custom-build integration independently of any proposed SDK feature.

Validation

Verified the SQL example against SQLite's official decimal source. Built a custom module with Emscripten 4.0.9, SQLite 3.53.0 and PowerSync core v0.4.13. Exercised PowerSync Web 1.39.1's real browser worker with exact scalar/window/10,000-row aggregate queries, persisted reopen and offline reads in Chrome (IndexedDB/OPFS) and WebKit (IndexedDB).

Ran Vale on both this change and the base page: the same two existing spelling errors remain (tokenizers, cmake); no additional findings. No links or navigation changed.

Changelog / Operational Notes

Documentation only. No SDK configuration, dependencies, schemas, environment variables, permissions, provider integrations or background jobs change.

@CLAassistant

CLAassistant commented Oct 9, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@simolus3 simolus3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks! This should be updated to mention the new additionalInitializationFunctions option, I also don't think we need it to be this detailed.


Similar to Dart on the web, loading extensions with `@powersync/web` is only possible with a custom `wa-sqlite` WebAssembly build. PowerSync [forks wa-sqlite](https://github.com/powersync-ja/wa-sqlite) for this reason, loading custom extension requires patching build definitions in that repository and adding an override from your npm package manager to patch `@journeyapps/wa-sqlite`.

When you build a custom module, pin the SQLite, wa-sqlite, PowerSync core and Emscripten versions. Compile the extension into the module and register it before opening databases, for example with `sqlite3_auto_extension()`. Keep the PowerSync core extension in the build.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IMO, "Keep the PowerSync core extension in the build." is kind of implied when we tell users to fork and override @journeyapps/wa-sqlite?


When you build a custom module, pin the SQLite, wa-sqlite, PowerSync core and Emscripten versions. Compile the extension into the module and register it before opening databases, for example with `sqlite3_auto_extension()`. Keep the PowerSync core extension in the build.

Deploy the generated JavaScript and WebAssembly files together. PowerSync's prebuilt database worker already contains wa-sqlite JavaScript, so a package override alone does not update that worker. Rebuild your database worker against the custom package and configure the SDK to use that worker. Use versioned asset filenames so a cached worker cannot load a module from a different build.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PowerSync's prebuilt database worker

FWIW, we typically rely on vite to recognize the worker as an entrypoint and bundle it, so a dependency override on wa-sqlite should actually work. Are you using react native web for this to be relevant?


Deploy the generated JavaScript and WebAssembly files together. PowerSync's prebuilt database worker already contains wa-sqlite JavaScript, so a package override alone does not update that worker. Rebuild your database worker against the custom package and configure the SDK to use that worker. Use versioned asset filenames so a cached worker cannot load a module from a different build.

Before running queries that need the extension, probe the actual PowerSync connection. For SQLite's decimal extension, this query checks scalar and aggregate functions:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Isn't the existence of decimal_cmp alone proof of the extension being bundled? I don't think we should recommend testing it.


The recommended OP-SQLite library has builtin support for custom extensions, and [excellent documentation](https://op-engineering.github.io/op-sqlite/docs/api#loading-extensions) on how to build and bundle them with your app.

For a statically linked extension, initialize it on each SQLite connection or register it with `sqlite3_auto_extension()` before creating connections. If you use SQLCipher, preserve its existing initialization hook. Adding native code requires a new native app build; a JavaScript-only update cannot add the extension to an installed binary.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Given that it complicates things, we should probably not recommend static extensions on native platforms (it's a different story on the web because dynamic loading isn't really a thing with wasm).

This branch has not been deployed

No deployments
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