Summary
When
expo-sqlite
is built with libSQL support (
useLibSQL
), there is no way to open a
local-only
libSQL database, even though the bundled
libsql
C library supports this via
libsql_open_file
. Additionally, on Android, setting
libSQLOptions.url
to a
file:
URL
(e.g.
file:local2.db
) causes the app to
crash on open
instead of failing gracefully.
Current Behavior
1. Local-only libSQL not supported
With
useLibSQL
enabled:
openDatabaseSync('local.db');
This fails with:
- InvalidArgumentsException("libSQLUrl must be provided")
From the Android implementation:
- flattenOpenOptions maps libSQLOptions.url → libSQLUrl and libSQLOptions.authToken →
libSQLAuthToken.
- In SQLiteModule.kt, when BuildConfig.USE_LIBSQL is true, the NativeDatabase constructor
always requires both:
- libSQLUrl != null
- libSQLAuthToken != null
- If present, it calls:
- libsql_open_remote(libSQLUrl, libSQLAuthToken) when libSQLRemoteOnly = true, or
- libsql_open(dbPath, libSQLUrl, libSQLAuthToken) (which internally uses
libsql_open_sync_with_config).
On iOS, SQLiteModuleLibSQL.swift has the same requirement (libSQLUrl and libSQLAuthToken)
and uses libsql_open_remote_with_webpki / libsql_open_sync_with_config.
The bundled libsql.h also exposes:
int libsql_open_file(const char *path,
libsql_database_t *out_db,
const char **out_err_msg);
but this is never called, so local-only libSQL databases cannot be opened.
2. file: URLs crash the app (Android)
Trying to work around this by using a file: URL:
openDatabaseSync('local2.db', {
libSQLOptions: { url: 'file:local2.db', authToken: '' },
});
On Android:
- This passes "file:local2.db" as primary_url into libsql_open_sync_with_config (via
libsql_open).
- That API expects a proper libSQL server URL + auth token; a file: URL is not supported in
this path.
- The result is a native error/exception and the app crashes during database open, rather
than raising a clear JS-level error.
Expected Behavior
1. Local-only libSQL mode
Allow opening a local-only libSQL database when useLibSQL is enabled, without requiring URL/
token, for example:
// Option A: implicit local-only when libSQLOptions is omitted
openDatabaseSync('local.db');
// Option B: explicit local-only flag
openDatabaseSync('local.db', {
libSQLOptions: { localOnly: true },
});
Internally, this should call libsql_open_file (or equivalent local-only API) instead of
libsql_open_sync_with_config / libsql_open_remote(_with_webpki).
2. Safe handling of file: URLs
Either:
- Treat file: URLs as a local-only hint and route them through a libsql_open_file-based
path, or
- Reject them with a clear JS error (e.g. “libSQLOptions.url must be an http(s) libSQL
server URL; local-only libSQL is not supported via file: URLs”).
In both cases, avoid native crashes.
Use Case
- Guest / offline mode: use a local-only embedded libSQL DB (no credentials).
- Authenticated mode: switch to a synced Turso/libSQL DB via libSQLOptions.url +
libSQLOptions.authToken.
Right now, once useLibSQL is enabled, all DBs must provide URL + token, and attempts to use
file: URLs to simulate local-only mode crash on Android.