Bare React Native SDK
Install and integrate @getrheo/react-native-bare — RheoProvider, Flow, native video/review adapters, and full API reference.
Package
@getrheo/react-native-bare — bare React Native entry point. Re-exports @getrheo/react-native-core and registers bare adapters:
| Capability | Adapter |
|---|---|
| Video layers | react-native-video |
| In-app review buttons | react-native-in-app-review |
Do not install @getrheo/react-native-expo alongside this package.
The public JavaScript API is identical to the Expo flavor — only native adapters and peer dependencies differ. Shared runtime concepts: SDK overview.
Runnable reference: getrheo/rheo-example-bare (public). Full-stack local API testing uses the private Rheo monorepo example via pnpm dev:local:app:react-native.
Install
pnpm add @getrheo/react-native-bare \
react react-native \
react-native-permissions react-native-gesture-handler react-native-reanimated \
react-native-linear-gradient react-native-svg lottie-react-native \
react-native-vector-icons @react-native-async-storage/async-storage \
react-native-safe-area-context react-native-in-app-review react-native-video@react-native-community/slider ships as a direct dependency of core.
Integrations (not SDK peers): react-native-appsflyer, react-native-purchases, react-native-purchases-ui — install only when used.
Native setup
iOS
cd ios && pod install- Permissions — for each
permissionKeyyour flows request, add entries viareact-native-permissionssetup_permissionsinPodfileand matching Info.plist usage strings (NSCameraUsageDescription,NSPhotoLibraryUsageDescription,NSCalendarsFullAccessUsageDescription, etc.). - Video —
react-native-videofollows its upstream linking guide (autolinking on RN 0.60+). - Fonts — link custom branding fonts or load at runtime before text renders.
Android
- Add
AndroidManifest.xmlpermissions for each capability (CAMERA,RECORD_AUDIO,READ_MEDIA_IMAGES,POST_NOTIFICATIONSon API 33+, etc.). - Rebuild after changing permissions.
Root layout
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { RheoProvider } from '@getrheo/react-native-bare';
const App = () => (
<SafeAreaProvider>
<GestureHandlerRootView style={{ flex: 1 }}>
<RheoProvider config={rheoConfig}>
<Navigation />
</RheoProvider>
</GestureHandlerRootView>
</SafeAreaProvider>
);react-native-gesture-handler must be imported at the app entry (see upstream docs) when using navigators.
OS permissions
Same built-in keys as Expo — notifications, camera, microphone, photo_library, contacts, calendar. The SDK calls react-native-permissions internally; there is no host permission callback.
Configure native projects per the react-native-permissions checklist. Missing setup → outcome denied.
Branding fonts
import { buildBrandingFontLoadMap } from '@getrheo/react-native-bare';
const fontMap = buildBrandingFontLoadMap(branding);
// Load with react-native-asset linking or a runtime loader before Flow mountsStep-by-step integration
1. Credentials
Copy publishable key from App settings → SDK credentials and channel public id from Channels. See SDK environment.
2. RheoConfig
import type { RheoConfig } from '@getrheo/react-native-bare';
const rheoConfig: RheoConfig = {
publishableKey: 'ob_pk_test_xxxxxxxx',
apiBaseUrl: __DEV__ ? 'http://10.0.2.2:4000' : undefined, // Android emulator → host
userId: persistedUserId, // load from AsyncStorage — do not omit on RN
sessionId: `sess_${Date.now()}`,
appVersion: DeviceInfo.getVersion(),
locale: 'en',
};Full field reference: Expo SDK — RheoConfig (same type).
3. RheoProvider
import { RheoProvider } from '@getrheo/react-native-bare';
<RheoProvider config={rheoConfig} prefetch={['ch_test_onboarding']}>
<RootNavigator />
</RheoProvider>Optional logLevel ("silent" | "warn" | "debug", default silent) controls SDK console diagnostics. See Diagnostics and logging.
4. <Flow />
import { Flow } from '@getrheo/react-native-bare';
import type { FlowTerminalSnapshot } from '@getrheo/react-native-bare';
const PaywallGate = () => (
<Flow
channelId="ch_live_paywall_01"
theme="light"
onFlowCompleted={(payload: FlowTerminalSnapshot) => {
navigation.replace('Home');
analytics.track('onboarding_complete', payload.correlation);
}}
fallback={<StaticPaywall />}
/>
);5. Custom UI with useFlow
Same API as Expo — import from @getrheo/react-native-bare:
import {
useFlow,
LayerRenderer,
ScreenChrome,
} from '@getrheo/react-native-bare';See Expo SDK — managed vs custom for the full useFlow / LayerRenderer pattern.
Identity
import { useRheoCustomUserId } from '@getrheo/react-native-bare';
const { setCustomUserId } = useRheoCustomUserId();
// After your auth session resolves:
setCustomUserId(backendUser.id);Persist userId yourself (AsyncStorage) so experiment bucketing stays stable across launches.
Manifest prefetch
Identical to Expo — import from @getrheo/react-native-bare:
import { prefetch, prefetchAll, useRheoPrefetch } from '@getrheo/react-native-bare';
<RheoProvider config={config} prefetch="all" />
// Imperative:
void prefetch('ch_test_…');In-app review
Requires react-native-in-app-review (listed in install command). Buttons with action.kind: "request_app_review" call the native review API with the same ~1.5s iOS delay behavior as Expo.
Video layers
video layers use react-native-video. Ensure the native module is linked and test on device — simulators may not reproduce all playback edge cases.
Events, terminal payloads, auth, paywalls
- Events — Event catalog
- Terminal snapshot — SDK overview
- Auth layers — Authentication layers
- RevenueCat — Integration guide
- AppsFlyer — Integration guide
Export reference
Same surface as @getrheo/react-native-expo — import from @getrheo/react-native-bare:
| Category | Exports |
|---|---|
| Provider | RheoProvider, useRheo, useRheoCustomUserId, useEventQueue |
| Flow UI | Flow, useFlow, LayerRenderer, ScreenChrome, DefaultResolveError |
| Prefetch | prefetch, prefetchAll, useRheoPrefetch |
| Auth | OAuthLoginProvider, EmailPasswordAuthProvider, useOAuthLogin, useEmailPasswordAuth |
| Integrations | presentRevenueCatPaywall, normalizeRcPaywallResult, attribution helpers |
| Types | RheoConfig, FlowTerminalSnapshot, UseFlowResult, FlowProps, manifest types |
| Errors | RheoChannelRequiredError, RheoChannelNotFoundError, RheoChannelArchivedError |
| Cache | clearManifestResolveCache, listManifestResolveCacheEntries, manifestResolveCacheKey |
HTTP API
| Endpoint | Purpose |
|---|---|
POST /v1/sdk/resolve | Channel manifest + assignment |
POST /v1/sdk/resolve-all | Batch prefetch |
POST /v1/sdk/events | Analytics batch |
Headers: Authorization: Bearer <publishableKey>, X-Rheo-Channel: <channelId> (resolve and per-channel event batches).
Expo vs bare — when to pick bare
| Choose bare when… | Choose Expo when… |
|---|---|
You own ios/ and android/ natively | You use Expo Router / dev client |
You already depend on react-native-video | You prefer expo-video + config plugins |
| You cannot use Expo prebuild | You want npx expo install peer alignment |