React Native SDK
The @flagify/react package works in React Native and Expo with zero additional setup. No separate package, no polyfills — the same SDK you use on the web works on mobile.
Requirements
| Dependency | Minimum version |
|---|---|
| React Native | 0.64+ |
| Expo SDK | 44+ |
| React | 18+ |
Getting started with Expo
1. Create a new project
npx create-expo-app@latest my-app
cd my-app
2. Install the SDK
npx expo install @flagify/react
3. Add the provider
Wrap your app with FlagifyProvider in your root layout. With Expo Router, this is app/_layout.tsx:
import { Stack } from 'expo-router';
import { FlagifyProvider } from '@flagify/react';
export default function RootLayout() {
return (
<FlagifyProvider
projectKey="my-project"
publicKey="pk_dev_abc123_xxxxxxxx"
options={{ realtime: true }}
>
<Stack />
</FlagifyProvider>
);
}
4. Use hooks in any screen
import { View, Text } from 'react-native';
import { useFlag } from '@flagify/react';
export default function HomeScreen() {
const showNewOnboarding = useFlag('new-onboarding');
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
{showNewOnboarding
? <Text>Welcome to the new experience!</Text>
: <Text>Welcome back!</Text>
}
</View>
);
}
Getting started with bare React Native
npm install @flagify/react
Wrap your root App.tsx with the provider:
import React from 'react';
import { FlagifyProvider } from '@flagify/react';
import { HomeScreen } from './screens/HomeScreen';
export default function App() {
return (
<FlagifyProvider
projectKey="my-project"
publicKey="pk_dev_abc123_xxxxxxxx"
options={{ realtime: true }}
>
<HomeScreen />
</FlagifyProvider>
);
}
Then use hooks in any component, exactly like the Expo example above.
Full example: feature-gated screen
import { View, Text, ActivityIndicator, StyleSheet } from 'react-native';
import { useFlag, useIsReady, useVariant } from '@flagify/react';
export default function ProfileScreen() {
const isReady = useIsReady();
const showPremiumBadge = useFlag('premium-badge');
const layout = useVariant('profile-layout', 'classic');
if (!isReady) {
return (
<View style={styles.center}>
<ActivityIndicator size="large" />
</View>
);
}
return (
<View style={styles.container}>
{showPremiumBadge && <Text style={styles.badge}>Premium</Text>}
{layout === 'modern'
? <ModernProfile />
: <ClassicProfile />
}
</View>
);
}
const styles = StyleSheet.create({
center: { flex: 1, justifyContent: 'center', alignItems: 'center' },
container: { flex: 1, padding: 16 },
badge: { color: '#0D80F9', fontWeight: 'bold', fontSize: 12 },
});
Real-time updates
SSE streaming works the same way in React Native as it does on the web. The SDK uses fetch streaming internally (not EventSource), which is natively supported in React Native 0.64+.
Set realtime: true on the provider and all hooks will automatically re-render when flags change.
Debug logging
To surface SSE connect/reconnect/sync logs from the underlying @flagify/node client, the SDK reads process.env.FLAGIFY_DEBUG === "1" at module load. Off by default — production bundles stay quiet.
React Native and Expo do not inline arbitrary process.env.* into the JS bundle out of the box: Expo only inlines vars prefixed with EXPO_PUBLIC_, and bare RN inlines nothing without a Babel plugin. The SDK does not look for prefixed copies, and localStorage does not exist on RN, so the activation paths are:
Option A — Babel plugin (works on Expo and bare RN). Install babel-plugin-transform-inline-environment-variables and add it to babel.config.js:
module.exports = {
plugins: [['transform-inline-environment-variables', { include: ['FLAGIFY_DEBUG'] }]],
};
Then start with the var set:
FLAGIFY_DEBUG=1 npx expo start --clear
Option B — bridge it manually. Set EXPO_PUBLIC_FLAGIFY_DEBUG=1 in your .env (Expo will inline it), and bridge to the SDK’s expected name in App.tsx / _layout.tsx before mounting <FlagifyProvider>:
if (process.env.EXPO_PUBLIC_FLAGIFY_DEBUG === '1') {
(process.env as Record<string, string>).FLAGIFY_DEBUG = '1';
}
The flag is read once at module load — reload the app after toggling.
Errors that indicate non-recoverable problems (auth failures, failed evaluation after sync, SSE parse errors) always log regardless.
Hooks reference
All hooks from @flagify/react work identically in React Native:
| Hook | Returns | Description |
|---|---|---|
useFlag(key) | boolean | Evaluate a boolean flag |
useVariant(key, fallback) | string | Get the winning variant |
useFlagValue<T>(key, fallback) | T | Get a typed flag value |
useIsReady() | boolean | Check if initial sync is complete |
useFlagifyClient() | Flagify | Access the underlying client |
For detailed API documentation, see the React SDK reference.