tursodatabase/turso · critical
Turso native module not loaded
Error message
Turso native module not loaded
What it means
Thrown by initLocalDatabase() during connect() when the JSI global __TursoProxy is not present on the JS runtime. The React Native binding is a thin TypeScript layer over a C++ JSI module that installs __TursoProxy as a runtime global (cpp/TursoHostObject.cpp). If the native part of @tursodatabase/sync-react-native was never built, linked, or is running in a runtime without JSI, the global is undefined and every local-only Database construction fails.
Solutions
- Disable remote JS debugging (Chrome debugger) — JSI only works with on-device/Hermes debugging via Flipper or the new debugger; then reload
- Rebuild the native app completely: `cd ios && pod install && cd .. && npx react-native run-ios` (or `./gradlew assembleDebug` on Android) so the JSI host object is compiled in
- If using Expo, switch from Expo Go to a development build (`npx expo run:ios` / `run-android`) since Expo Go cannot load custom native modules
- Verify android/build.gradle has minSdkVersion 21+ and that the package is autolinked (check it appears in `pod install` output / MainActivity modules)
- As a last resort, clean and rebuild: `watchman watch-del-all`, delete node_modules, ios/Pods, and build directories, then reinstall
Example fix
// before: app works in normal mode but throws 'Turso native module not loaded' when remote debugging
// Dev Menu -> Debug JS Remotely -> reload:
const db = new Database({ path: getDbPath('local.db') });
await db.connect(); // throws: __TursoProxy is undefined in the Chrome debug runtime
// after: keep JS execution on device (Hermes) and rebuild native after install
// package.json scripts stay the same; just avoid remote JS debugging and rebuild:
// cd ios && pod install && cd ..
// npx react-native run-ios
const db = new Database({ path: getDbPath('local.db') });
await db.connect(); Defensive patterns
Strategy: validation
Validate before calling
// Before constructing a Database, confirm the JSI global exists
import { getDbPath, Database } from '@tursodatabase/sync-react-native';
declare const __TursoProxy: unknown;
export function nativeModuleAvailable(): boolean {
return typeof __TursoProxy !== 'undefined';
}
if (!nativeModuleAvailable()) {
throw new Error(
'Turso native module missing: rebuild the app (pod install / gradle) and disable remote JS debugging'
);
}
const db = new Database({ path: getDbPath('local.db') }); Type guard
declare const __TursoProxy: unknown;
function hasTursoNative(globalThis: Record<string, unknown>): boolean {
return typeof globalThis['__TursoProxy'] !== 'undefined';
} Try / catch
try {
await db.connect();
} catch (e) {
if (e instanceof Error && e.message.includes('native module not loaded')) {
// Environment problem, not a data problem: instruct rebuild / disable remote debug
showSetupError('Rebuild the native app and disable remote JS debugging (JSI required).');
}
throw e;
} Prevention
- Always rebuild the native app after installing or upgrading the package (pod install on iOS, gradle build on Android)
- Never run the app with Chrome remote JS debugging when using JSI-based libraries; use on-device debugging
- Use an Expo development build, not Expo Go, for custom native modules
- Fail fast at startup with a typeof __TursoProxy check so the failure names the environment cause
When it happens
Trigger: Creating `new Database({ path })` (no url) and calling `await db.connect()` while __TursoProxy is undefined: running the app without rebuilding the native binary after adding the dependency, skipping `cd ios && pod install`, debugging JS remotely in Chrome (the Chrome remote debugger replaces the JSI runtime with a plain JS engine that has no JSI globals), or running inside Expo Go where custom native code is not included.
Common situations: Fresh install where `npm install @tursodatabase/sync-react-native` ran but the iOS pods / Android gradle build were never refreshed; switching a project to the new architecture or upgrading React Native without rebuilding the app binary; enabling 'Debug JS Remotely' which detaches JSI; using Expo Go instead of a development build (`npx expo run:ios`).
Related errors
- jsContextPointer == 0
- @tursodatabase/sync-react-native: Failed to install JSI…
- @tursodatabase/sync-react-native: JSI bindings not found on…
- @tursodatabase/sync-react-native: Native module not found…
- Unknown column type
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/19c1582ea57e0ae7.
Report an issue: GitHub.
Appendix: source
Thrown at bindings/react-native/src/Database.ts:122
if (this._connected) {
return;
}
if (this._isSync) {
await this.initSyncDatabase();
} else {
this.initLocalDatabase();
}
this._connected = true;
}
/**
* Initialize local-only database
*/
private initLocalDatabase(): void {
if (typeof __TursoProxy === 'undefined') {
throw new Error('Turso native module not loaded');
}
const dbConfig = {
path: this._opts.path,
async_io: false, // use blocking IO for local database
};
// Create native database (path normalization happens in C++ JSI layer)
this._nativeDb = __TursoProxy.newDatabase(this._opts.path, dbConfig);
// Open database
this._nativeDb.open();
// Get connection
this._connection = this._nativeDb.connect();
}
/**View on GitHub (pinned to 244cde92a7)