Native integration
Configure native builds, runtime resources, and process isolation for a React Native app.
The React Native package uses Swift on iOS and Kotlin on Android. It supplies TypeScript APIs over the same native PostgreSQL runtime used by those platform SDKs.
Choose a runtime mode
Direct mode is the default. Use one application-owned handle and share it through a service. For process isolation, select broker mode when configuring the native build; follow mobile broker setup.
Both modes run database work away from JavaScript and return promises. They provide one PostgreSQL session, not a connection pool.
Expo integration
The quickstart uses the config plugin to prepare native projects. The plugin stages iOS runtime resources, configures local CocoaPods dependencies, and applies the Android Gradle integration. Expo Go cannot load this custom native module.
For an existing Expo native project, rerun prebuild when the plugin configuration changes, then rebuild the app. Review generated native changes alongside any native customizations you maintain.
Native projects managed directly
Use the package's same platform integration when maintaining native projects without Expo prebuild. Match versions to the installed React Native package rather than mixing platform SDK releases.
On Android, add mavenCentral() to plugin and dependency repositories and apply the dev.oliphaunt.android plugin to the app module using version 0.3.0. The React Native package supplies its Kotlin dependency. Set seedProfile.set("standard") in the app's oliphaunt block for a new database. Configure selected extensions there and rebuild.
The manual steps below configure direct mode. On iOS, set deployment target 17.0 or later and install the standard seed dependency shown in the quickstart. The npm package includes local COliphaunt and Oliphaunt podspecs plus a staging tool. Before running CocoaPods, stage the app payload using the package's exported integration helper. Save this script in your app root and run it with Node:
import fs from 'node:fs';
import path from 'node:path';
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const packageRoot = path.dirname(require.resolve('@oliphaunt/react-native/package.json'));
const plugin = require(path.join(packageRoot, 'app.plugin.js'));
const options = plugin.normalizeOptions({ seedProfile: 'standard', extensions: [] });
const iosRoot = path.resolve('ios');
await plugin.stageIosAppPayload(process.cwd(), iosRoot, options);
const podfile = path.join(iosRoot, 'Podfile');
fs.writeFileSync(
podfile,
plugin.insertIosPodfileBlock(fs.readFileSync(podfile, 'utf8'), options),
);The Podfile must already call use_native_modules!. The helper adds the local platform podspecs and staged payload dependency. Run bundle exec pod install from ios, then rebuild the app. Keep this preparation step in the application's native build process.
Extension resources
Install the native extension packages your app uses before plugin or manual setup. For example:
npm install @oliphaunt/extension-vector@0.3.0The Expo plugin discovers installed extension packages. You can narrow the packaged selection with its extensions filter. Pass imported extension descriptors to Oliphaunt.open({ extensions: [...] }). Selection at runtime verifies the installed resources; it cannot add missing native code. See the extension recipe.
Lifecycle
Explicitly await close() to observe cleanup. Module invalidation and finalizers provide fallback cleanup only. Cancel active SQL through cancel(), then observe its outcome. The app remains responsible for backgrounding policy and persistent storage; see Ship a mobile database.