React Native
The Sukko TypeScript SDK works in React Native out of the box. No separate native SDK needed — @sukko/sdk and @sukko/websocket run on React Native's JavaScript runtime, and @sukko/react hooks work identically to web React.
React Native uses the exact same packages as web React. If you've already integrated Sukko in a web app, the code is identical.
Install
npm install @sukko/sdk @sukko/websocket @sukko/react
Setup Provider
// App.tsx
import { SukkoProvider } from '@sukko/react';
import { WebSocketTransport } from '@sukko/websocket';
export default function App() {
return (
<SukkoProvider
options={{
transport: new WebSocketTransport({ url: 'ws://your-gateway:3000' }),
getToken: async () => {
const res = await fetch('https://your-api.com/auth/sukko-token');
return res.text();
},
}}
>
<ChatScreen />
</SukkoProvider>
);
}
Subscribe and Display Messages
useSubscription takes an array of channels and returns the latest message; accumulate a list with onMessage for a scrollback view:
import { useState } from 'react';
import { useSubscription, useConnectionState, type TypedMessage } from '@sukko/react';
import { View, Text, FlatList } from 'react-native';
function ChatScreen() {
const [messages, setMessages] = useState<TypedMessage[]>([]);
const { state } = useConnectionState();
useSubscription({
channels: ['general.chat'],
onMessage: (msg) => setMessages((prev) => [...prev, msg]),
});
return (
<View>
<Text>Status: {state}</Text>
<FlatList
data={messages}
keyExtractor={(_, i) => String(i)}
renderItem={({ item }) => <Text>{JSON.stringify(item.data)}</Text>}
/>
</View>
);
}
Publish a Message
import { useSukkoClient } from '@sukko/react';
import { TouchableOpacity, Text } from 'react-native';
function SendButton() {
const client = useSukkoClient();
return (
<TouchableOpacity onPress={() => client.publish('general.chat', { text: 'Hello from RN!' })}>
<Text>Send</Text>
</TouchableOpacity>
);
}
Platform Notes
- WebSocket — React Native includes a built-in WebSocket implementation. The
@sukko/websockettransport uses it automatically. - Background — WebSocket connections are closed when the app is backgrounded on iOS/Android. The SDK auto-reconnects when the app returns to the foreground and automatically replays any Kafka messages missed while offline — no manual call. Where a replay can't be confirmed the SDK surfaces a
possible_gapmarker on the client'smessages()stream instead of dropping silently (see Automatic Recovery). The per-channelposcursor is held in memory, so it persists across background/foreground cycles within the same app session. - Client ID persistence — Unlike web, React Native has no
localStorage. The SDK generates a freshclient_ideach time the app cold-starts, so gap-free replay does not persist across app restarts on React Native. Replay still works within the same app session (across background/foreground cycles). - Token refresh — The
getTokencallback is called automatically before token expiry, same as web.
Push Notifications ENTERPRISE
Mobile push (FCM/APNs) is an Enterprise feature — registering android/ios devices below Enterprise is rejected with 403 EDITION_LIMIT. (Web Push, used by browser apps, is Pro — see the push notifications guide.)
Register a device for push with @sukko/react-native. It bundles no push library — you provide a small MessagingAdapter over whatever your app already uses (@react-native-firebase/messaging, expo-notifications, …), and the SDK registers the device token with the gateway and re-registers automatically when it rotates.
npm install @sukko/react-native
import { enableMobilePush, type MessagingAdapter } from '@sukko/react-native';
import { Platform } from 'react-native';
import messaging from '@react-native-firebase/messaging';
// A thin adapter over your app's messaging library — the SDK depends on none directly.
const adapter: MessagingAdapter = {
requestPermission: async () => {
const status = await messaging().requestPermission();
return status === messaging.AuthorizationStatus.AUTHORIZED;
},
getToken: () => messaging().getToken(),
onTokenRefresh: (cb) => messaging().onTokenRefresh(cb),
};
const registration = await enableMobilePush(client, adapter, {
platform: Platform.OS === 'ios' ? 'ios' : 'android',
channels: ['acme.alerts'],
onError: (err) => console.warn('push re-registration failed', err),
});
// registration.deviceId — persist it (it rotates when the token refreshes).
// Later: await registration.disable();
The SDK is a push registrar, not a receiver — the device receives notifications through the OS (FCM/APNs) and your app's own handler, never over the Sukko socket.
The gateway routes push by platform (ios → APNs). An iOS app using Firebase holds an FCM token that platform: "ios" can't express — use APNs directly on iOS, and FCM on Android.
Next Steps
- React Integration — Same API, web-specific examples
- Authentication — Token management
- SDK Reference — Full hooks API reference
- React Native Push Reference —
enableMobilePush+MessagingAdapter