tursodatabase/turso · critical · Error
@tursodatabase/sync-react-native: Native module not found. M
Error message
@tursodatabase/sync-react-native: Native module not found. Make sure you have properly linked the library. - iOS: Run 'pod install' in your ios directory - Android: Make sure the package is properly included in your MainApplication.java
What it means
This package installs JSI bindings at import time: it reads NativeModules.Turso and throws immediately if it is undefined, meaning React Native autolinking/manual linking never registered the native module. Because it is a module-scope throw, any import of '@tursodatabase/sync-react-native' fails the whole JS bundle, not just a call.
Source
Thrown at bindings/react-native/src/index.ts:54
// Enums
TursoStatus,
TursoType,
} from './types';
// Re-export classes
export { Database } from './Database';
export { Statement } from './Statement';
// Export file system configuration function
export { setFileSystemImpl } from './internal/ioProcessor';
// Get the native module
const TursoNative: TursoNativeModule | undefined = NativeModules.Turso;
// Check if native module is available
if (!TursoNative) {
throw new Error(
`@tursodatabase/sync-react-native: Native module not found. Make sure you have properly linked the library.\n` +
`- 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;
View on GitHub (pinned to bad083fafb)
Solutions
- iOS: run cd ios && pod install, then rebuild the app fully
- Android: run a clean build (./gradlew clean) so autolinking regenerates; verify the package resolves in react-native.config.js
- Expo: use a development build (npx expo run:ios / run:android), never Expo Go
- Jest: add a setupFiles mock (jest.mock('react-native', () => ({ NativeModules: { Turso: { install: () => true } } }))) or mock the SDK module
- Reset Metro cache: npx react-native start --reset-cache
Example fix
// jest.setup.js (before)
// importing the SDK in tests throws: Native module not found
// jest.setup.js (after)
jest.mock('react-native', () => ({
NativeModules: { Turso: { install: () => true } },
}));
// jest.config.js: setupFiles: ['<rootDir>/jest.setup.js'] Defensive patterns
Strategy: validation
Validate before calling
// Check availability BEFORE importing the SDK (it throws at import time)
import { NativeModules, Platform } from 'react-native';
const nativeAvailable =
(Platform.OS === 'ios' || Platform.OS === 'android') &&
!!NativeModules.Turso;
let db: typeof import('@tursodatabase/sync-react-native');
if (nativeAvailable) {
db = require('@tursodatabase/sync-react-native');
} Type guard
function isTursoNativeAvailable(): boolean {
try {
const { NativeModules } = require('react-native');
return typeof NativeModules.Turso?.install === 'function';
} catch {
return false;
}
} Try / catch
let sdk: typeof import('@tursodatabase/sync-react-native');
try {
sdk = require('@tursodatabase/sync-react-native');
} catch (e) {
if (String((e as Error).message).includes('Native module not found')) {
throw new Error('Run pod install / rebuild, or use an Expo dev build instead of Expo Go');
}
throw e;
} Prevention
- After adding/upgrading the package always run pod install and rebuild native
- Never import the SDK in Jest/Node without a NativeModules mock in setupFiles
- Use an Expo development build, not Expo Go
- Keep a CI smoke test that imports the SDK on-device to catch linking regressions early
When it happens
Trigger: iOS without pod install after adding the package; Android where the package is not registered in MainApplication (old-architecture manual linking); running inside Expo Go, which has no third-party native code; importing the package in Jest or Node (no native runtime at all); autolinking broken by a custom react-native.config.js.
Common situations: Fresh clone where a teammate committed package.json but pods/gradle were never refreshed; switching from a dev build to Expo Go for quick testing; Jest unit tests importing a module that transitively pulls in the SDK; monorepo where the app does not autolink libraries from nested node_modules.
Related errors
- Turso native module not loaded
- Unable to get database path for this platform. Make sure the
- Encryption is not supported in this build
- Encryption is not supported in this build
- push() is only available for sync databases
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/bb1428cbd8acb3ea.
Report an issue: GitHub.