Build With React Native
Install the React Native package, build a native app binary, configure exact extensions, use JSI transport, and wire lifecycle APIs.
Use the React Native SDK in Expo and New Architecture React Native apps. The JS package owns TypeScript DX, config plugin behavior, TurboModule/JSI transport, and installed-app integration. Runtime behavior is delegated to Swift on Apple platforms and Kotlin on Android.
React Native needs a native app binary
Oliphaunt includes Swift and Kotlin runtime code. Use an Expo development build or a React Native app binary so the native runtime is present when JavaScript loads.
Choose the native app path first
Oliphaunt ships native runtime code. The JavaScript bundle can call it only after the installed app binary includes the Swift and Kotlin pieces.
Expo development build
Install
npx expo install @oliphaunt/react-nativeNative build
Run prebuild, then build iOS or Android.
Best for
Expo apps that include native modules, selected extensions, and development tooling.
Verify first
Config plugin output, native module loading, JSI ArrayBuffer roundtrip.
React Native New Architecture app
Install
npm install @oliphaunt/react-nativeNative build
Run CocoaPods and Gradle after package or extension changes.
Best for
Existing RN apps that already own native projects and New Architecture builds.
Verify first
Autolinking, Codegen, TurboModule availability, platform resource packaging.
Platform-native app
Install
Use the Swift or Kotlin SDK directly.
Native build
Build through Xcode or Gradle without the RN package.
Best for
iOS, macOS, or Android apps without a React Native JavaScript surface.
Verify first
Swift actor or Kotlin coroutine lifecycle, app storage, selected extensions.
Install
Install the package for the app path you own, then build the native app binary.
The runtime uses Swift and Kotlin code, so package installation alone is not the
last step. The installed app must contain the native module and selected runtime
resources before JavaScript calls Oliphaunt.open().
Expo apps:
npx expo install @oliphaunt/react-native
npx expo prebuild
npx expo run:ios
npx expo run:androidExpo apps use the config plugin so selected native runtime and extension artifacts are included in the app build.
{
"expo": {
"plugins": [
[
"@oliphaunt/react-native",
{
"extensions": ["vector"]
}
]
]
}
}React Native apps without Expo still use the same package, but native projects own the equivalent Pod, Gradle, and resource configuration. Rebuild after changing native runtime or extension selection because those choices affect the installed app binary.
Open and query
Open a database from TypeScript, run SQL, and close it when the app no longer needs the handle.
import { Oliphaunt } from '@oliphaunt/react-native';
const db = await Oliphaunt.open({
root: 'main.oliphaunt',
engine: 'nativeDirect',
extensions: ['vector'],
});
const rows = await db.query('SELECT 1::text AS value');
const value = rows.getText(0, 'value');
await db.close();Keep the database handle in app state or a service object. Multiple JavaScript objects share the same mobile direct session through the platform SDK.
Create app data
Use the SQL helpers for application queries. This keeps most React Native code away from PostgreSQL protocol details:
await db.execute(`
CREATE TABLE IF NOT EXISTS notes (
id bigserial PRIMARY KEY,
title text NOT NULL,
body text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now()
)
`);
await db.query(
'INSERT INTO notes (title, body) VALUES ($1, $2) RETURNING id::text AS id',
['First note', 'Stored in an embedded PostgreSQL root'],
);
const notes = await db.query(
'SELECT id, title FROM notes ORDER BY id DESC LIMIT 20',
);
const firstTitle = notes.getText(0, 'title');Reach for raw protocol APIs only when building adapters, COPY flows, or streaming paths that need PostgreSQL wire messages directly.
Configure
Configure root, mode, selected exact extensions, durability, startup identity, and native runtime overrides through the JS API and config plugin. Build-time extension selection controls what ships in the app bundle; runtime root configuration controls where app data lives.
Keep build-time and runtime settings separate. The config plugin controls native
artifacts in the installed app. Oliphaunt.open() controls the database root,
mode, durability, and extension activation for that app run.
Choose a mode
React Native starts with nativeDirect on mobile. The database work is
delegated to Swift on Apple platforms and Kotlin on Android, so
capabilities() is the source of truth for additional broker or server mode
reports. OpenConfig.engine currently accepts nativeDirect only.
Use binary transport
New Architecture builds use binary ArrayBuffer/JSI transport for raw protocol bytes and chunked streaming. Bulk payloads stay in binary buffers.
Treat JSI transport as the bulk-byte boundary. Small configuration and lifecycle calls use the TurboModule API; protocol payloads and streamed chunks stay in binary buffers.
Handle lifecycle
Use the SDK lifecycle hooks around background/foreground transitions. Direct mobile mode is same-root logically reopenable inside one resident app process. Broker and server runtimes add a process boundary on targets that advertise those modes.
Call the JavaScript lifecycle API from app-level lifecycle handlers. The Swift and Kotlin SDKs own the platform-specific details underneath that call.
Select extensions
Select exact SQL extension names in configuration. The native app packages
include only selected extensions plus declared dependencies. CREATE EXTENSION
succeeds when the selected runtime resources contain that extension for the
target platform.
Back up and restore
Use the React Native backup and restore APIs instead of copying platform storage directories from JavaScript. The SDK delegates archive validation and root materialization to Swift or Kotlin, so platform storage rules stay native.
This guide is complete when
Use these checks before moving from a first query to application code.
Native app binary
The app runs in an Expo development build or React Native New Architecture binary.
Binary transport
Raw protocol bytes and streamed chunks move through JSI ArrayBuffer paths.
Platform delegation
Apple behavior flows through Swift, Android behavior flows through Kotlin, and JS owns DX.
Config output
The config plugin selects exact extensions and native runtime assets for the app artifact.
Troubleshooting
Check the development build, Expo config plugin output, autolinking, TurboModule codegen, native module availability, selected extension artifacts, and platform SDK errors. For database runtime behavior, follow the Swift or Kotlin SDK page for the target platform.