Skip to main content
Version: 2.0.0

React Native SDK

Get your Featureflow account at featureflow.com

GitHub: https://github.com/featureflow/featureflow-react-native

Installation

# npm
npm install @featureflow/react-native-sdk @react-native-async-storage/async-storage

# yarn
yarn add @featureflow/react-native-sdk @react-native-async-storage/async-storage

For iOS, install CocoaPods dependencies:

cd ios && pod install

Peer Dependencies

  • react >= 16.8.0
  • react-native >= 0.60.0
  • @react-native-async-storage/async-storage >= 1.17.0

Quick Start

1. Wrap Your App with the Provider

import React from 'react';
import { FeatureflowProvider } from '@featureflow/react-native-sdk';
import MainApp from './MainApp';

const FF_KEY = 'sdk-js-env-YOUR_KEY_HERE';

function App() {
const user = {
id: 'user-123',
attributes: {
tier: 'gold',
country: 'australia'
}
};

return (
<FeatureflowProvider apiKey={FF_KEY} user={user}>
<MainApp />
</FeatureflowProvider>
);
}

export default App;

2. Use Feature Flags in Components

import React from 'react';
import { View, Text } from 'react-native';
import { useFeatureflow, useBooleanFlag } from '@featureflow/react-native-sdk';

function MainApp() {
// Option 1: Boolean flag hook (recommended for on/off flags)
const { isOn, isLoading } = useBooleanFlag('new-feature');

// Option 2: Client for more control
const featureflow = useFeatureflow();
const variant = featureflow.evaluate('experiment-color').value();

if (isLoading) {
return <Text>Loading...</Text>;
}

return (
<View style={{ backgroundColor: variant === 'blue' ? 'blue' : 'red' }}>
{isOn ? <NewFeature /> : <OldFeature />}
</View>
);
}

Hooks

useFeatureflow()

Returns the Featureflow client for evaluating features and tracking goals:

import { useFeatureflow } from '@featureflow/react-native-sdk';

function MyComponent() {
const featureflow = useFeatureflow();

const isOn = featureflow.evaluate('my-feature').isOn();
const variant = featureflow.evaluate('my-feature').value();
const isPremium = featureflow.evaluate('pricing-tier').is('premium');

// Track a goal (for A/B testing)
const handlePurchase = () => {
featureflow.goal('purchase-completed');
};

return (
<Button onPress={handlePurchase}>
{isPremium ? 'Premium Checkout' : 'Standard Checkout'}
</Button>
);
}

useBooleanFlag(key, options?)

Convenience hook for on/off flags:

import { useBooleanFlag } from '@featureflow/react-native-sdk';

function MyComponent() {
const { isOn, isOff, isLoading } = useBooleanFlag('dark-mode');

// With default value
const { isOn: betaEnabled } = useBooleanFlag('beta-feature', {
defaultValue: true
});

return isOn ? <DarkTheme /> : <LightTheme />;
}

useStringFlag(key, defaultValue?)

Hook for multi-variant flags:

import { useStringFlag } from '@featureflow/react-native-sdk';

function PricingPage() {
const { value, isLoading } = useStringFlag('pricing-tier', 'standard');

switch (value) {
case 'premium':
return <PremiumPricing />;
case 'basic':
return <BasicPricing />;
default:
return <StandardPricing />;
}
}

useFeatures()

Returns all evaluated features:

import { useFeatures } from '@featureflow/react-native-sdk';

function DebugPanel() {
const features = useFeatures();

return (
<View>
{Object.entries(features).map(([key, value]) => (
<Text key={key}>{key}: {value}</Text>
))}
</View>
);
}

useFeatureflowStatus()

Check client initialization status:

import { useFeatureflowStatus } from '@featureflow/react-native-sdk';

function AppLoader() {
const { isLoading, error, isReady } = useFeatureflowStatus();

if (isLoading) return <SplashScreen />;
if (error) return <ErrorScreen error={error} />;
return <MainApp />;
}

Updating User Context

Update the user after login to re-evaluate features:

const featureflow = useFeatureflow();

// After user logs in
await featureflow.updateUser({
id: 'new-user-id',
attributes: {
tier: 'premium',
beta: true
}
});

Configuration Options

<FeatureflowProvider
apiKey="sdk-js-env-YOUR_KEY"
user={user}
config={{
defaultFeatures: {
'new-feature': 'off',
'experiment': 'control'
},
timeout: 5000,
offline: false
}}
loadingComponent={<LoadingScreen />}
>
<App />
</FeatureflowProvider>
OptionTypeDefaultDescription
defaultFeaturesobject{}Default values for offline/loading states
offlinebooleanfalseRun in offline mode (no network requests)
timeoutnumber10000Request timeout in milliseconds
initOnCachebooleanfalseEmit INIT event when loading from cache
applicationstringundefinedNames this app (e.g. 'mobile-app') so the dashboard can attribute SDK usage and flag evaluations to it — see Application Tags

Advanced Usage

Manual Client Initialization

For more control over initialization timing:

import { init, FeatureflowProviderWithClient } from '@featureflow/react-native-sdk';

function App() {
const [client, setClient] = useState(null);

useEffect(() => {
init('sdk-js-env-YOUR_KEY', { id: 'user-123' }).then(setClient);
}, []);

if (!client) return <SplashScreen />;

return (
<FeatureflowProviderWithClient client={client}>
<MainApp />
</FeatureflowProviderWithClient>
);
}

Event Handling

Listen to Featureflow events:

import { useFeatureflow, events } from '@featureflow/react-native-sdk';

function MyComponent() {
const featureflow = useFeatureflow();

useEffect(() => {
const handleInit = (features) => {
console.log('Features loaded:', features);
};

featureflow.on(events.INIT, handleInit);
return () => featureflow.off(events.INIT, handleInit);
}, [featureflow]);
}

Available events: INIT, LOADED, LOADED_FROM_CACHE, ERROR, UPDATED

TypeScript Support

The SDK includes comprehensive type definitions:

import type {
FeatureflowUser,
FeatureflowConfig,
FeatureflowClient,
EvaluatedFeatures
} from '@featureflow/react-native-sdk';

const user: FeatureflowUser = {
id: 'user-123',
attributes: {
tier: 'gold',
countries: ['AU', 'NZ']
}
};

Next Steps

License

Apache-2.0