Skip to main content

Installation

npm install @omniretail/omniflags-react-native @react-native-async-storage/async-storage
Follow the AsyncStorage native setup to link the native module. Peer dependencies: React Native 0.68+, @react-native-async-storage/async-storage 1.0+

Setup

import { OmniFlagsProvider } from '@omniretail/omniflags-react-native';

export default function App() {
  return (
    <OmniFlagsProvider sdkKey="pk_live_...">
      <RootNavigator />
    </OmniFlagsProvider>
  );
}
Flags are available immediately on launch from the local cache, with a background refresh running in parallel. This applies on subsequent launches even when the device is offline.

First launch

No cache exists on a fresh install, so flags start loading. Gate on isLoading from useFlagStatus if your app needs flags before it can render:
import { useFlagStatus } from '@omniretail/omniflags-react-native';

function AppShell() {
  const { isLoading } = useFlagStatus();
  if (isLoading) return <SplashScreen />;
  return <RootNavigator />;
}
After the first snapshot is cached this won’t trigger again, even offline.

Hooks

Same hooks as the React SDK, imported from @omniretail/omniflags-react-native.

useFlag

Boolean flag evaluation. Re-renders only when this flag’s value changes.
import { useFlag } from '@omniretail/omniflags-react-native';

function CheckoutScreen({ customerId }: { customerId: string }) {
  const chargeDeliveryFee = useFlag('checkout.charge-delivery-fee', { customerId });
  return (
    <View>
      <Text>{chargeDeliveryFee ? 'Delivery fee applies' : 'Free delivery'}</Text>
    </View>
  );
}
ParameterTypeDefaultDescription
flagKeystringrequired{projectKey}.{flagKey}
contextEvaluationContext{}Targeting attributes
defaultValuebooleanfalseFallback when flag is missing, wrong type, or client not ready

useFlagValue

Returns the typed value of any flag — string, number, or object.
import { useFlagValue } from '@omniretail/omniflags-react-native';

function PromoBanner({ customerId }: { customerId: string }) {
  const colour = useFlagValue('product-listing.promo-banner-colour', 'blue', { customerId });
  return (
    <View style={{ backgroundColor: colour }}>
      <Text>Limited time offer</Text>
    </View>
  );
}
const config = useFlagValue<CheckoutConfig>('checkout.config', defaultConfig, { customerId });
ParameterTypeRequiredDescription
flagKeystringyes{projectKey}.{flagKey}
defaultValueTyesFallback value
contextEvaluationContextnoTargeting attributes

useFlagVariant

Returns the full EvaluationResult — variant key, reason, and rule ID.
import { useFlagVariant } from '@omniretail/omniflags-react-native';

function BannerWithAnalytics({ customerId }: { customerId: string }) {
  const result = useFlagVariant('product-listing.promo-banner-colour', { customerId });

  useEffect(() => {
    analytics.track('flag_evaluated', {
      flag: 'product-listing.promo-banner-colour',
      variant: result.variant,
      reason: result.reason,
    });
  }, [result.variant]);

  return <Banner colour={result.value as string} />;
}
FieldTypeDescription
valueunknownResolved flag value
variantstring | nullMatched variant key
reasonEvaluationReasonSee reason codes
ruleIdstring | nullMatched rule ID, if any
errorCodeErrorCode | nullSet when reason is ERROR

useFlagStatus

Current state of the flag client.
import { useFlagStatus } from '@omniretail/omniflags-react-native';

function DebugOverlay() {
  const { isLoading, isFetching, origin, error } = useFlagStatus();
  return (
    <Text style={styles.debug}>
      Flags: {isLoading ? 'loading' : origin} {isFetching ? '(refreshing)' : ''}
    </Text>
  );
}
FieldTypeDescription
isLoadingbooleantrue until the first snapshot loads (cache or network)
isFetchingbooleantrue while a network request is in flight
origin'NONE' | 'CACHE' | 'SERVER'Source of the active snapshot
errorError | nullLast fetch error

useSetFlagContext

Sets a global evaluation context for the whole provider tree. Individual hook calls that pass their own context will be merged with it — per-call attributes win on conflict.
import { useSetFlagContext } from '@omniretail/omniflags-react-native';

function AuthenticatedNavigator({ user }: { user: CurrentUser }) {
  useSetFlagContext({
    customerId: user.id,
    country: user.country,
    platform: Platform.OS,
  });

  return <RootNavigator />;
}
Clears on unmount.
ParameterTypeDescription
contextEvaluationContext | undefinedPass undefined to clear explicitly.

Evaluation context

Attributes used to match targeting rules and assign rollout buckets. Pass per-hook or once globally via useSetFlagContext.
useFlag('checkout.charge-delivery-fee', {
  customerId: '4821',
  country: 'Nigeria',
  city: 'Lagos',
  platform: 'android',
  appVersion: '4.1.0',
});
AttributeTypeNotes
customerIdstring | numberPrimary bucketing key
agentIdstring | numberUsed when customerId is absent
businessIdstring | number
businessBranchIdstring | number
countrystringe.g. "Nigeria", "Ghana"
citystring
platformstringweb, ios, android
appVersionstringSemver string
Any extra key-value pairs are forwarded to targeting rules as custom attributes.
Rollout and traffic splits require a bucketing key (customerId, agentId, etc.). Without one the SDK returns the flag’s default value with MISSING_TARGETING_KEY.

Offline support

The last successful snapshot is persisted locally and loaded on the next launch before any network activity.
  • origin is 'CACHE' while a background fetch is pending, 'SERVER' once it completes.
  • On fetch failure origin stays 'CACHE' and flags keep serving from the cached snapshot.

Foreground refresh

A snapshot refresh is triggered automatically when the app returns to the foreground. Flag changes made in the dashboard reach active users without requiring an app restart.