Skip to main content

Overview

This developer guide will assist you in configuring your React Native application for Feature Flags using the Mixpanel React Native SDK. Feature Flags allow you to control the rollout of your features, conduct A/B testing, and manage application behavior without deploying new code. Feature Flags in the React Native SDK work across iOS, Android, and React Native Web platforms. For complete React Native SDK documentation, see the React Native SDK guide.

Prerequisites

Before implementing Feature Flags, ensure:
  • You are on an Enterprise subscription plan and have the latest version of the SDK installed (minimum supported version is v3.5.0). If not, install with npm install mixpanel-react-native.
  • You have your Project Token from your Mixpanel Project Settings.
  • For iOS native apps, run cd ios && pod install after installing the SDK.
Data Residency: Use the server URL that matches your Mixpanel project’s data residency region:
  • US (default): https://api.mixpanel.com
  • EU: https://api-eu.mixpanel.com
  • India: https://api-in.mixpanel.com

Execution Modes

The React Native SDK operates in two modes that affect how feature flags are evaluated: The mode is determined by the useNative parameter in the Mixpanel constructor:

Flag Initialization

Initializing the SDK with feature flags enabled requires passing featureFlagsOptions with enabled: true to the init() method. This enables making an outbound request to Mixpanel servers with the current user context. The server will assign the user context to a variant for each feature flag according to how they are configured in the Mixpanel UX. The response will include an assigned variant for each flag that the user context is in a rollout group for. If a flag is not returned, it most likely signifies that the user was excluded by filtering rules or the rollout percentage for the flag. Example Usage
If your flag is configured with a Variant Assignment Key other than distinct_id or device_id for any of the feature flags in your project, then the call to initialize feature flags must include those keys. For example, for a Variant Assignment Key company_id, you would set up the SDK as follows:
If you are using Runtime Targeting in any of the feature flags in your project, then any properties that you use in targeting should be included in a custom_properties node within the context:

Flag Persistence

By default (networkOnly), the SDK fetches fresh flag assignments and waits for the network response before variant calls complete. You can enable persistence to cache assignments so they are available immediately on subsequent launches. In JavaScript mode, persistence uses the same AsyncStorage adapter as the rest of the SDK. In native mode, persistence is handled by the underlying iOS and Android SDKs. Configure a persistence.variantLookupPolicy on featureFlagsOptions: networkFirst. The SDK waits for the network on every launch. If the network call fails, the persisted value is returned as a fallback. Async getter calls block until the fetch completes (or the fallback is resolved).
persistenceUntilNetworkSuccess. Persisted variants are returned immediately on launch. Each getter call while serving persisted data triggers a background network fetch (deduplicated, only one fetch runs at a time). If the fetch fails, persisted data continues to be served and the next getter call retries the fetch. Once a fetch succeeds, the in-memory state updates and subsequent calls no longer trigger background fetches.
To customize the TTL (default is 24 hours), pass persistenceTtlMs in milliseconds:

Variant source

Every variant returned by getVariant / getVariantSync carries a variant_source field indicating where the value came from: "network", "persistence", or "fallback". Variants served from persistence also include persisted_at_in_ms, the epoch timestamp in milliseconds when the variant set was persisted.

$experiment_started properties

When a variant is served, the $experiment_started exposure event includes:
  • $variant_source. Either "network" or "persistence".
  • $persisted_at_in_ms. Epoch milliseconds when the variant set was persisted (persistence only).
Persistence is scoped to the current distinct_id. Calling identify() with a new ID or calling reset() clears persisted flag state and triggers a fresh fetch.

Flag Reload

Following initialization, you can reload feature flag assignments in several ways:

Reload via identify

After a user logs in or out of your application and you call identify, a feature flag reload will be triggered.

Manual Reload

You can manually reload flags at any time:

Update Context

updateContext is available in both native and JavaScript modes. It updates the feature flags context after initialization and triggers a reload with the new values.
In JavaScript mode, pass { replace: true } to replace the context entirely instead of merging.
In native mode, the SDK always merges the new context with the existing context. The { replace: true } option is accepted for API parity but has no effect on native.

Flag Evaluation

The SDK provides both asynchronous (Promise-based) and synchronous methods for evaluating flags. Async methods return Promises that resolve once flags are ready. This is the recommended approach as it handles the case where flags may not yet be loaded. Experiment Flags: Get Variant Value
Feature Gates: Check if Flag is Enabled/Disabled
Get Full Variant Object Use getVariant to retrieve the full variant object, which includes metadata like experiment_id:

Sync Evaluation

Synchronous methods return values immediately without waiting. Use these when you need to evaluate flags in render paths or other synchronous contexts.
Sync methods return the fallback value if flags have not finished loading. Always check areFlagsReady() before relying on sync results.

Get All Flag Assignments

You can retrieve all feature flag assignments at once. These methods do not trigger $experiment_started exposure events. Synchronous getAllVariantsSync() returns a JavaScript Map keyed by feature name. If flags have not been loaded yet, it returns an empty Map.
Asynchronous getAllVariants returns a Promise resolving to a Map. If flags have not been loaded yet, it will attempt to fetch them before returning. On failure, it resolves to an empty Map rather than rejecting.

Exposure Events

Calling isEnabled, isEnabledSync, getVariantValue, getVariantValueSync, getVariant, or getVariantSync triggers tracking an exposure event, $experiment_started, to your Mixpanel project if the user context is in a rollout group for the feature flag. The exposure event is deduplicated per feature name for the lifetime of the SDK instance. getAllVariants and getAllVariantsSync do not fire exposure events.

Method Name Aliases

The React Native SDK supports both camelCase and snake_case method names, aligned with mixpanel-js conventions:

Frequently Asked Questions

What if I’m not receiving any flags on SDK initialization?

  1. Check your project token:
  1. Review flag configuration:
  • Make sure your feature flag is enabled.
  • Check the flag’s rollout percentage. User contexts that are not assigned to the rollout percentage will not receive flags.
  • If you are using a targeting cohort, verify on the Mixpanel ‘Users’ page that the user’s distinct_id is a member of that cohort.
  1. Review SDK parameters:
  • Ensure featureFlagsOptions with enabled: true is passed to init().
  • If using a custom Variant Assignment Key, ensure it is included in the context object.
  • If using Runtime Targeting, ensure all properties used in targeting are included in the custom_properties object within context.
  1. Check flags readiness: Use areFlagsReady() to check if flags have been loaded before using sync evaluation methods.
  2. Enable debug logging: Call mixpanel.setLoggingEnabled(true) to see detailed information about flag requests and responses.

Which mode should I use?

  • Bare React Native apps (iOS/Android): Use native mode (new Mixpanel(token, true)) for best performance, as it delegates to the optimized native SDKs.
  • React Native Web: Use JavaScript mode (new Mixpanel(token, true, false)).