tursodatabase/turso · error · Error

@tursodatabase/sync-react-native: JSI bindings not found on…

Error message

@tursodatabase/sync-react-native: JSI bindings not found on global object. This is a bug.

What it means

install() reported success, but the global __TursoProxy object it is supposed to install on the JavaScript global was not found. The code itself labels this 'This is a bug': the native module and the JSI proxy are out of sync, i.e. the native binary you are running does not match the JS package that is checking for the proxy. It is not fixable through configuration.

Solutions

  1. Align versions: make package.json and the native dependency (CocoaPods / gradle) point at the same release of the SDK
  2. Fully rebuild the native app: iOS - pod update the Turso pod, clean DerivedData, rebuild from Xcode; Android - ./gradlew clean, uninstall the old APK, reinstall
  3. Restart Metro with --reset-cache so stale JS bundles cannot mask the fix
  4. If matched versions still reproduce, file a bug against the SDK including both version numbers - the message explicitly marks it as one

Example fix

# before: only the JS side was upgraded
npm install @tursodatabase/sync-react-native@latest # app still crashes at import

# after: upgrade both sides and rebuild from scratch
cd ios && pod update Turso && rm -rf ~/Library/Developer/Xcode/DerivedData && xcodebuild
cd android && ./gradlew clean && ./gradlew installDebug
Defensive patterns

Strategy: validation

Validate before calling

// In dev, verify the proxy exists right after a dynamic import
const mod = await import('@tursodatabase/sync-react-native');
if (typeof (globalThis as any).__TursoProxy === 'undefined') {
  throw new Error('JS/native version skew: rebuild native (pod update / gradlew clean) to match the npm package');
}

Type guard

function hasTursoProxy(g: typeof globalThis): boolean {
  return typeof (g as any).__TursoProxy !== 'undefined';
}

Try / catch

try { await import('@tursodatabase/sync-react-native'); } catch (e) { if (String(e.message).includes('JSI bindings not found')) { // native binary does not match JS - clean rebuild both, then report if it persists } throw e; }

Prevention

When it happens

Trigger: Import-time check failing because a TursoNative.install() from an older native build returns true without registering __TursoProxy (or registers a differently-named global) while the freshly upgraded JS package expects the new contract - typically after bumping only package.json or only the pods/gradle dependency.

Common situations: Half-completed upgrade: new npm package with stale native pods or a cached APK/IPA; iOS derived-data staleness serving an old binary; downgrading the JS package below the native binary's version.

Related errors


AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20). Data as JSON: /api/errors/72cd06ad584ac9c1. Report an issue: GitHub.

Appendix: source

Thrown at bindings/react-native/src/index.ts:74

    `- iOS: Run 'pod install' in your ios directory\n` +
    `- Android: Make sure the package is properly included in your MainApplication.java`
  );
}

// Install the JSI bindings
const installed = TursoNative.install();
if (!installed) {
  throw new Error(
    '@tursodatabase/sync-react-native: Failed to install JSI bindings. Make sure the New Architecture is enabled.'
  );
}

// Get the proxy that was installed on the global object
// __TursoProxy is declared globally in types.ts
const TursoProxy: TursoProxyType = __TursoProxy;

if (!TursoProxy) {
  throw new Error(
    '@tursodatabase/sync-react-native: JSI bindings not found on global object. This is a bug.'
  );
}

/**
 * Helper function to construct a database path in a writable directory.
 *
 * @param filename - Database filename (e.g., 'mydb.db')
 * @returns Absolute path to the database file
 *
 * @example
 * ```ts
 * import { getDbPath, connect } from '@tursodatabase/sync-react-native';
 *
 * const dbPath = getDbPath('mydb.db');
 * const db = await connect({ path: dbPath });
 * ```
 */

View on GitHub (pinned to 244cde92a7)