> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appdna.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# React Native Feature Flags

> Toggle features on and off without app updates

<Info>
  **Supported on:** iOS SDK `1.0.70+` · Android SDK `1.0.42+` · React Native SDK `1.0.7+` (New Architecture only)
</Info>

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

```typescript theme={null}
import { AppDNA } from '@appdna-ai/react-native-sdk';

declare function enableDarkMode(): void;

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`:

```typescript theme={null}
declare function showCompactHome(): void;
declare function showDetailedHome(): void;
declare function showDefaultHome(): void;

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

```typescript theme={null}
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: () => void): () => void` | Register a callback that fires when flag values change. The callback receives no arguments — re-read the flags you care about. Returns an unsubscribe function. |

## Using Flags with Experiments

Gate a feature behind a flag, then run an experiment to test its impact:

```typescript theme={null}
declare function showCompactWorkoutUI(): void;
declare function showDetailedWorkoutUI(): void;
declare function showDefaultWorkoutUI(): void;
declare function showLegacyWorkoutUI(): void;

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:

```typescript theme={null}
declare function reloadHomeScreen(): void;

// The callback receives NO arguments — re-read the flags you care about.
const unsubscribe = AppDNA.features.onChanged(() => {
  // Reload any UI that depends on feature flags.
  reloadHomeScreen();
});

// Later, when you no longer need updates:
unsubscribe();
```

<Note>
  The callback fires once per refresh, not per flag. Re-read the flags you care about inside the callback.
</Note>

## Full Example

```typescript theme={null}
import { AppDNA } from '@appdna-ai/react-native-sdk';

declare function showAISuggestions(): void;

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: () => {
    void AppDNA.paywall.present('premium_paywall', { placement: 'feature_gate' });
  },
  onUnlocked: () => {
    showAISuggestions();
  },
});

// React to remote changes
AppDNA.features.onChanged(() => {
  // Re-evaluate gates when flags refresh.
});
```

<Note>
  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 1 hour).
</Note>
