SDK
The AppDispatch SDK (@appdispatch/react-native) is a single package that handles OTA updates, feature flags, and health reporting. It wraps OpenFeature for flag evaluation and includes built-in error tracking with flag correlation.
Installation
npm install @appdispatch/react-nativePeer dependencies: react (≥18), react-native (≥0.70). expo-updates (≥0.20) is optional but required for OTA update features.
Setup
Initialize the SDK at module level (before any component renders), then wrap your app with AppDispatchProvider:
import {
AppDispatch,
AppDispatchProvider,
useOTAUpdates,
} from '@appdispatch/react-native'
AppDispatch.init({
baseUrl: 'https://api.appdispatch.com',
projectSlug: 'my-app',
apiKey: 'YOUR_API_KEY',
channel: 'production',
})
export default function RootLayout() {
useOTAUpdates()
return (
<AppDispatchProvider>
<YourApp />
</AppDispatchProvider>
)
}That’s it. AppDispatch.init() sets up the OpenFeature provider and health reporter. AppDispatchProvider wraps your app with the OpenFeature context and starts health monitoring on mount. useOTAUpdates() checks for OTA updates, handles device ID generation, and applies critical updates immediately.
Evaluating flags
Flag hooks are re-exported from @appdispatch/react-native — no need to import from @openfeature/react-sdk directly:
import {
useBooleanFlagValue,
useStringFlagValue,
useNumberFlagValue,
useObjectFlagValue,
} from '@appdispatch/react-native'
function MyComponent() {
// Boolean — kill switches, feature toggles
const enabled = useBooleanFlagValue('new-checkout', false)
// String — A/B variants, theme names
const variant = useStringFlagValue('theme', 'default')
// Number — limits, thresholds
const limit = useNumberFlagValue('max-items', 10)
// JSON — complex config objects
const config = useObjectFlagValue('settings', {})
}The second argument is the default value — returned when the flag doesn’t exist, is disabled, or the provider hasn’t loaded yet.
For more detailed evaluation results, use the Details variants:
import { useBooleanFlagDetails } from '@appdispatch/react-native'
const { value, reason, variant } = useBooleanFlagDetails('new-checkout', false)Setting evaluation context
For targeting rules, set the evaluation context with the user’s identity and any attributes you want to target on:
import { OpenFeature } from '@openfeature/react-sdk'
import { Platform } from 'react-native'
// Set after login — include any attributes your targeting rules use
OpenFeature.setContext({
targetingKey: currentUser.id,
kind: 'user',
name: currentUser.displayName,
email: currentUser.email,
plan: currentUser.plan, // 'free', 'pro', 'enterprise'
platform: Platform.OS, // 'ios', 'android'
appVersion: '2.4.1',
country: currentUser.country,
})targetingKey(required for targeting) — unique identifier for user list and percentage rollout ruleskind— context type, defaults to"user". Use"device","organization","service", or"environment"for non-user contextsname— display name shown in the Contexts dashboard- All other properties are custom attributes available for attribute targeting rules and segment conditions
Update the context whenever attributes change (e.g., plan upgrade):
OpenFeature.setContext({
...existingContext,
plan: 'pro',
})Health reporting
Health reporting is built into the SDK — no separate package needed. The AppDispatchProvider starts health monitoring automatically on mount and stops it on unmount.
To record custom events or errors manually, access the health reporter via AppDispatch.instance:
// Record custom business events
AppDispatch.instance.health.recordEvent('checkout_success')
// Record errors manually
AppDispatch.instance.health.recordError('Payment gateway timeout')
// Force flush buffered events
await AppDispatch.instance.health.flush()See Health Reporter for details on auto-capture, flag correlation, and event deduplication.
Configuration options
| Option | Type | Default | Description |
|---|---|---|---|
baseUrl | string | required | AppDispatch API URL |
projectSlug | string | required | Project slug from the dashboard |
apiKey | string | — | API key for authenticated requests |
channel | string | — | Channel (e.g., production, staging) |
deviceId | string | — | Stable device identifier. Auto-generated and persisted if omitted. |
platform | string | — | "ios" or "android". Auto-detected from React Native if omitted. |
updateId | string | — | Current OTA update ID. Auto-detected from expo-updates if omitted. |
runtimeVersion | string | — | Runtime version. Auto-detected from expo-updates if omitted. |
flagPollIntervalMs | number | 30000 | How often to refresh flag definitions (ms) |
flagFlushIntervalMs | number | 60000 | How often to send evaluation reports (ms) |
healthFlushIntervalMs | number | 30000 | How often to send health events (ms). Set to 0 to disable. |
autoCaptureErrors | boolean | true | Auto-capture JS errors and crashes via ErrorUtils |
trackAppLaunches | boolean | true | Track app launches via AppState |
maxBufferSize | number | 100 | Max health events before forcing a flush |
How it works
AppDispatch.init()creates the OpenFeature provider and health reporter, wiring flag correlation automatically- The provider fetches all flag definitions in one request and caches them in memory
- Polls for flag definition updates every 30 seconds (configurable)
- Flag evaluations happen locally — no network call per evaluation
- Deterministic hashing ensures stable rollout bucketing
- Evaluations are batched and reported every 60 seconds for analytics
- Health events (errors, crashes, launches) are buffered and flushed every 30 seconds
- Errors are correlated with active flag states at the moment they occur
See OpenFeature Provider for the full evaluation architecture.
Advanced: accessing internals
The AppDispatch.instance object exposes the underlying provider and health reporter for advanced use cases:
// Access the OpenFeature provider directly
const provider = AppDispatch.instance.provider
const flags = provider.getFlags() // All loaded flag definitions
// Access the health reporter directly
const health = AppDispatch.instance.health