
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
@flybits/react-native-flightkit
Advanced tools
React Native Flightkit is modular React Native SDK for personalized UI and Content within your mobile applications
A modular, native-parity React Native SDK for integrating Flybits Context and Concierge experiences.
This library handles session management, context data collection, rich UI rendering (Zones/Content), and deep link routing seamlessly out-of-the-box. The core SDK surface is explicitly exported for direct client access: FlybitsManager, FlybitsSlot (and ref handleAction), Session, idp, registerPushToken, handlePushPayload, ActionLink, and related types.
Install the core library. react-native-webview and react-native-safe-area-context are included as dependencies (not peer dependencies), so a single install is enough—no need to add them in your app unless you use them elsewhere.
npm install @flybits/react-native-flightkit
# or
yarn add @flybits/react-native-flightkit
If you want to enable push notifications and contextual analytics tracking via pushes, you must also install the Firebase messaging packages:
npm install @react-native-firebase/app @react-native-firebase/messaging
Note: If you do not install the Firebase libraries, the SDK will safely bypass push registration and continue functioning normally for all in-app contextual experiences.
The FlybitsManager handles SDK configuration, session connection via Identity Providers (IDPs), and background Context worker initialization in one step. Call it as early as possible in your app lifecycle.
You pass a flybitsConnect function that performs the actual login using FlybitsSession.connect() and an IDP from idp (e.g. FlybitsIdp.AnonymousIDP). Authentication is refactored so that clients handle the Identity Provider (IDP) logic (e.g. anonymous, JWT, API key) and pass the credentials to Flybits via flybitsConnect. If the SDK already has a stored session, it will reuse it and will not call flybitsConnect.
import {
FlybitsManager,
Session,
idp,
type InitializeProps,
} from '@flybits/react-native-flightkit';
const host = 'YOUR-HOST';
const projectID = 'YOUR-PROJECT-ID';
const flybitsConfig: InitializeProps = {
host,
flybitsConnect: () => {
return FlybitsSession.connect(new FlybitsIdp.AnonymousIDP({ projectID }));
},
logLevel: 'errors', // 'verbose' | 'errors' | 'silent'
pushProvider: 'FCM', // 'FCM' | 'APNS' | 'NONE'
};
// 1. Initialize the SDK (call once at app startup)
const bootFlybits = async () => {
try {
await FlybitsManager.initialize(flybitsConfig);
// If a session was already stored, it is rehydrated automatically.
console.log('Connected!', FlybitsSession.userToken);
} catch (error) {
console.error('Flybits Failed to Boot', error);
}
};
// 2. Disconnect (Logout)
const logoutUser = async () => {
// Automatically shuts down the Context worker, deletes push tokens, and drops the FlybitsSession.
// Call this inside your app's logout function
await FlybitsManager.disconnect();
};
Use FlybitsSession.connect() with an IDP instance from idp. Common options:
FlybitsSession.connect(new FlybitsIdp.AnonymousIDP({ projectID: '...' }))FlybitsSession.connect(new FlybitsIdp.JWTSignedIDP({ jwt: '...' })) — use the JWT returned by your SAML/SSO provider.FlybitsSession.connect(new FlybitsIdp.APIKeyIDP({ projectID, email, apiKey }))idp export for other IDP classes (e.g. OAuth, signed token).Important: If a user logs out and logs back in (or switches accounts) without calling disconnect(), the device token will be registered to Flybits twice. This will result in the device receiving duplicate push notifications when a single push is sent. Always call FlybitsManager.disconnect() to clean up the previous session's push tokens before initializing a new one.
The <FlybitsSlot /> component is the main UI container. It automatically fetches Zone data, renders the Concierge web experience, and securely handles all internal deep links. Theming is applied dynamically (light/dark) via the theme prop: 'light' | 'dark' | 'system' (default 'system' uses the device setting).
import { FlybitsSlot } from '@flybits/react-native-flightkit';
const MyScreen = () => {
return (
<FlybitsSlot
refID="my_zone_reference_id"
theme="light"
// Optional: Intercept custom actions
onAction={(action) => {
if (action.protocol === 'custom') {
console.log('Intercepted custom action:', action.rawStr);
}
}}
/>
);
};
react-native-flightkit features a 3-Tier Cascade UI Override System for Loading, Error, and Empty states.
<FlybitsSlot />.
<FlybitsSlot
refID="credit_card_offers"
custom={{
loadingOverride: <Text>Loading Offers...</Text>,
emptyPlaceholder: <Text>No offers today. Check back tomorrow!</Text>,
errorOverride: (onRetry) => (
<Button title="Failed to load. Tap to retry." onPress={onRetry} />
)
}}
/>
FlybitsManager.initialize({
// ...
globalLoadingUI: <MyCustomSpinner />,
globalErrorUI: (onRetry) => <MyCustomErrorScreen retryBtn={onRetry} />,
});
With the optional Firebase dependencies (@react-native-firebase/app, @react-native-firebase/messaging), Context Analytics (Viewed, Engaged, ComponentEngaged) for push is automated by the SDK. You handle the notification in your own way (e.g. custom UI, navigation, or deep links). We only provide the action link in case you need it: pass onPushActionTapped in FlybitsManager.initialize() and we will call it with the action link string when the user taps a Flybits notification (app in foreground, background, or launched from closed state by tapping the notification). You can then use it however you like—e.g. to run the action in a slot with flybitsSlotRef.current.handleAction(new ActionLink(actionLinkStr)). For foreground, you can also call FlybitsManager.handlePushPayload(remoteMessage) when you show the notification and the user taps it.
Using a different push library? You can still use our functions. Use registerPushToken(provider, manualToken) with your own token to register the device with Flybits, and call FlybitsManager.handlePushPayload(remoteMessage) when the user taps a notification. handlePushPayload only acts on Flybits pushes (payload provider === 'flybits'). If the notification is not from Flybits, we return immediately and do nothing—your other notifications are unaffected.
onPushActionTappedWhen the user taps a notification while the app is in the background, or when the app was closed and the user opens it by tapping the notification, the SDK reports analytics and, if you provided onPushActionTapped in FlybitsManager.initialize(), calls it with the action link string. Handle the notification your way; use the action link only if you need it (e.g. to run in a slot):
await FlybitsManager.initialize({
host,
flybitsConnect: () => FlybitsSession.connect(new FlybitsIdp.AnonymousIDP({ projectID })),
onPushActionTapped: (actionLinkStr) => {
// e.g. navigate to the Concierge screen, then:
// conciergeSlotRef.current?.handleAction(new ActionLink(actionLinkStr));
},
pushProvider: 'FCM',
});
If a push arrives while your app is in the foreground, Firebase will not show a heads-up by default. Handle the notification your way (e.g. show it with @notifee/react-native or React Native Alert). If you want Flightkit to report analytics and optionally use the action link, call FlybitsManager.handlePushPayload(remoteMessage) when the user taps it. The action link is available in the payload if you need it (e.g. to run in a slot).
import messaging from '@react-native-firebase/messaging';
import { Alert } from 'react-native';
import { FlybitsManager } from '@flybits/react-native-flightkit';
messaging().onMessage(async remoteMessage => {
Alert.alert(
'A new FCM message arrived!',
remoteMessage.notification?.body,
[
{
text: 'View Offer',
onPress: () => {
// Tell Flightkit the user tapped the notification!
// This will execute the Action Link and report analytics exactly like a background push.
FlybitsManager.handlePushPayload(remoteMessage);
},
},
{ text: 'Cancel', style: 'cancel' }
],
{ cancelable: false }
);
});
pushProvider ConfigurationBecause different apps have different Firebase setups, you can force the SDK to use a specific push network:
APNS: Standard for iOS production.FCM: Standard for Android. (Can also be used on iOS).NONE: Disables push registration entirely.The device token is registered with Flybits only when a new session is created (e.g. first launch or after logout). It is not re-registered when the session is rehydrated from storage, so anonymous users do not get duplicate push registrations. Calling FlybitsManager.disconnect() removes the token on logout.
registerPushToken)registerPushToken is exported so you can retry registration (e.g. after the user grants notification permission) or use it with any push library: pass a manualToken as the second argument so clients not using react-native-firebase can still register their device token with Flybits and use handlePushPayload when the user taps a notification (only Flybits payloads are processed; others are ignored).
import { registerPushToken } from '@flybits/react-native-flightkit';
// With Firebase: token is fetched automatically
await registerPushToken('FCM'); // or 'APNS' on iOS
// Without Firebase: pass your own token
await registerPushToken('FCM', 'your-device-token-string');
The SDK safely decodes and executes a massive array of Action Links out of the box using React Native's Linking API.
| Scheme | Descriptions | Behavior |
|---|---|---|
details:// | Content Details | Slides up the internal FlybitsOverlay |
concierge:// | Zone Navigation | Navigates the slot to a new Zone/Filter |
web:// or browser:// | In-App Browser | Decodes URL and opens InAppBrowser |
https:// | External Web | Safely opens OS Default Browser |
universalLink:// | OS specific | Opens ios= param on iOS, android= on Android |
mail:// or phone | Communication | Opens Mail or Dialer app |
app:// | Deep Link Wrapper | Safely unwraps and opens other native apps |
custom:// | Client Handled | Emitted to <FlybitsSlot onAction={...} /> |
To run an action link in a specific <FlybitsSlot ref={flybitsSlotRef} />, use a ref: flybitsSlotRef.current.handleAction(new ActionLink(actionLinkStr)). Useful when handling push notifications and you want to target a particular slot.
You can control the verbosity of the SDK through the initializer. Log levels match the core SDK: verbose | errors | silent. All log lines use a standardized [rn-fk-info], [rn-fk-detailed], [rn-fk-debug], or [rn-fk-error] prefix with timestamps.
FlybitsManager.initialize({
logLevel: 'errors', // 'verbose' | 'errors' | 'silent'
});
silent: No logs.errors: Errors only ([rn-fk-error]).verbose: Errors, info, detailed, and debug (full logging).On Android, when a WebView is inside a ScrollView, the list can jump to the WebView on first touch. This is a known react-native-webview upstream issue (see also #2057, #2360). This library applies a fix via a postinstall script based on the workarounds discussed there.
How it works: A postinstall script (scripts/patch-webview-android.js) injects a requestFocus() override into react-native-webview’s native Android code. Based on the workarounds in that GitHub thread, the script locates protected void onScrollChanged(...) in RNCWebView.java and inserts the override just before it. The script is version-agnostic: it works with any react-native-webview version (e.g. 13.x, 14.x) as long as the onScrollChanged structure in RNCWebView.java remains the same. If that structure changes in a future release, the script skips applying and prints a warning (the patch is ignored; no build failure).
react-native-webview@>=13.0.0. You can upgrade and still get the fix when the structure matches.Apache-2.0. See LICENSE for the full text.
Made with create-react-native-library
FAQs
React Native Flightkit is modular React Native SDK for personalized UI and Content within your mobile applications
We found that @flybits/react-native-flightkit demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.