Supported on: iOS SDK 1.0.61+ · Android SDK 1.0.33+ · React Native SDK 1.0.4+
The feature flags module lets you enable or disable features remotely from the AppDNA Console. Flags are evaluated locally from cached config — no network call, no latency on the hot path.
Check a Flag
import { AppDNA } from '@appdna/react-native-sdk';
if (await AppDNA.features.isEnabled('dark_mode')) {
enableDarkMode();
}
isEnabled() returns false by default if the flag does not exist or config has not loaded.
Multi-Variant Flags
For flags that carry a string, number, or JSON payload (rather than a simple on/off), read the value with getVariant:
const variant = await AppDNA.features.getVariant('home_layout');
switch (variant) {
case 'compact':
showCompactHome();
break;
case 'detailed':
showDetailedHome();
break;
default:
showDefaultHome();
}
getVariant returns unknown — cast to the type you configured in the Console.
Module Access
const features = AppDNA.features;
Module Methods
| Method | Signature | Description |
|---|
isEnabled | isEnabled(flag: string): Promise<boolean> | Check if a feature flag is enabled |
getVariant | getVariant(flag: string): Promise<unknown> | Get the variant payload for a multi-variant flag |
onChanged | onChanged(callback: (flags: Record<string, unknown>) => void): () => void | Register a callback that fires when flag values change. Returns an unsubscribe function. |
Using Flags with Experiments
Gate a feature behind a flag, then run an experiment to test its impact:
if (await AppDNA.features.isEnabled('new_workout_ui')) {
const variant = await AppDNA.experiments.getVariant('workout_ui_test');
switch (variant) {
case 'compact':
showCompactWorkoutUI();
break;
case 'detailed':
showDetailedWorkoutUI();
break;
default:
showDefaultWorkoutUI();
}
} else {
showLegacyWorkoutUI();
}
React to Flag Changes
Register an onChanged callback to re-render UI when the SDK receives an updated config from the server:
const unsubscribe = AppDNA.features.onChanged(() => {
// Reload any UI that depends on feature flags.
reloadHomeScreen();
});
// Later, when you no longer need updates:
unsubscribe();
The callback fires once per refresh, not per flag. Re-read the flags you care about inside the callback.
Full Example
import { AppDNA } from '@appdna/react-native-sdk';
export class FeatureGate {
async checkAccess(
feature: string,
options: { onLocked: () => void; onUnlocked: () => void },
): Promise<void> {
if (await AppDNA.features.isEnabled(feature)) {
options.onUnlocked();
} else {
options.onLocked();
}
}
}
// Usage
const gate = new FeatureGate();
await gate.checkAccess('ai_suggestions', {
onLocked: () => {
AppDNA.paywall.present('premium_paywall', { placement: 'feature_gate' });
},
onUnlocked: () => {
showAISuggestions();
},
});
// React to remote changes
AppDNA.features.onChanged(() => {
// Re-evaluate gates when flags refresh.
});
Feature flags are managed in the Console under Settings > Feature Flags. Toggle a flag and it takes effect on the next SDK config refresh (default 5 minutes).