React Native SDK (JSI)
The React Native SDK uses C FFI to call the Rust evaluation core directly from JavaScript via React Native's JavaScript Interface (JSI). This avoids the async bridge overhead and delivers synchronous, near-native evaluation performance.
Installation
npm install @sidekick-flags/react-native
# or
yarn add @sidekick-flags/react-nativeiOS
cd ios && pod installAndroid
The native library is linked automatically via CMake. No additional steps required.
Quick Start
import { SidekickNativeClient } from '@sidekick-flags/react-native'
const client = new SidekickNativeClient({
serverUrl: 'https://flags.yourcompany.com',
sdkKey: 'your-sdk-key',
})
// Connect on app start (typically in App.tsx)
useEffect(() => {
client.connect()
return () => client.disconnect()
}, [])
// Evaluate flags synchronously anywhere
const enabled = client.isEnabled('new-onboarding', userId, {
plan: user.plan,
country: user.country,
})API Reference
new SidekickNativeClient(options)
| Option | Type | Required | Description |
|---|---|---|---|
serverUrl | string | Yes | Base URL of your Sidekick server |
sdkKey | string | No | SDK key for authentication |
reconnectDelayMs | number | No | SSE reconnect delay in ms (default: 5000) |
client.connect(): void
Initiates the SSE connection in the background. Flags are loaded as they arrive; isEnabled() returns false for unknown flags during bootstrap.
Unlike the web SDK, connect() does not return a Promise — it fires and forgets, consistent with React Native's event-driven model.
client.isEnabled(flagKey, userKey, attributes): boolean
Synchronous flag evaluation via JSI. Runs on the JS thread, calls into the Rust library without bridging overhead.
client.disconnect(): void
Tears down the SSE connection. Call in your cleanup effect.
Usage with React Navigation
// App.tsx
import { NavigationContainer } from '@react-navigation/native'
import { SidekickNativeClient } from '@sidekick-flags/react-native'
import { createContext, useContext, useEffect, useState } from 'react'
const FlagContext = createContext<SidekickNativeClient | null>(null)
export function useFlags() {
return useContext(FlagContext)!
}
const flagClient = new SidekickNativeClient({
serverUrl: process.env.EXPO_PUBLIC_SIDEKICK_URL!,
sdkKey: process.env.EXPO_PUBLIC_SIDEKICK_KEY,
})
export default function App() {
useEffect(() => {
flagClient.connect()
return () => flagClient.disconnect()
}, [])
return (
<FlagContext.Provider value={flagClient}>
<NavigationContainer>
{/* ... */}
</NavigationContainer>
</FlagContext.Provider>
)
}// screens/HomeScreen.tsx
import { useFlags } from '../App'
import { useUser } from '../hooks/useUser'
export function HomeScreen() {
const flags = useFlags()
const user = useUser()
const showNewUI = flags.isEnabled('new-home-ui', user.id, {
plan: user.plan,
beta: user.isBeta ? 'true' : 'false',
})
return showNewUI ? <NewHomeUI /> : <LegacyHomeUI />
}Expo Compatibility
The SDK is compatible with Expo managed workflow via the Expo Dev Client. It is not compatible with Expo Go (which doesn't support native modules).
npx expo install @sidekick-flags/react-native
npx expo prebuildPlatform Support
| Platform | Architecture | Status |
|---|---|---|
| iOS | arm64 | Supported |
| iOS Simulator | x86_64 / arm64 | Supported |
| Android | arm64-v8a | Supported |
| Android | armeabi-v7a | Supported |
| Android | x86_64 | Supported |