React Native SDK 1.0.0
Deployment status:
@limelink/react-native@1.0.0is not yet available on npm; public latest remains0.1.1. Use this guide to prepare the 1.0.0 migration, and run the install command only after npm publishes 1.0.0.
The wrapper pins Android and iOS native SDK 1.0.0 and exposes one cross-platform incoming-link/result contract.
Requirements
| Requirement | Supported |
|---|---|
| React | 19.1.0 or later |
| React Native | 0.81.0 or later |
| Runtime | Hermes with New Architecture |
| Host | Community CLI or Expo Development Build |
| Android | API 24 or later |
| iOS | iOS 12 or later |
The package runs through Legacy Native Module interoperability on Hermes with the New Architecture. Legacy Architecture, JSC, Expo Go, and web are unsupported. RN 0.81.5 Android and clean pod installation have passed, while its iOS simulator row remains pending. RN 0.85 Community, RN 0.86 Expo Development Build, and RN 0.86.2 packed-package fixtures provide additional build evidence.
Install after publication
npm install @limelink/react-native@1.0.0
# or: yarn add @limelink/react-native@1.0.0
# or: pnpm add @limelink/react-native@1.0.0
The package resolves org.limelink:limelink-aos-sdk:1.0.0 and LimelinkIOSSDK 1.0.0. The Android Maven artifact is public; the iOS CocoaPod and npm wrapper must both be publicly resolvable before a clean React Native iOS install can succeed.
Android consumers add the LimeLink public Maven repository. Expo Development Builds add "plugins": ["@limelink/react-native"]; the app configures its owned link domains separately.
Initialize and listen
import { useEffect } from 'react';
import LimeLink from '@limelink/react-native';
export function LimeLinkSetup() {
useEffect(() => {
const subscription = LimeLink.addLinkListener({
onDeeplinkReceived(result) {
if (isAllowedDestination(result.deeplinkUrl)) {
navigateTo(result.deeplinkUrl);
}
},
onDeferredDeepLinkNotFound() {},
onDeeplinkError(error) {
showSafeFallback(error.code, error.message, error.platform);
},
});
LimeLink.initialize({
projectId: '550e8400-e29b-41d4-a716-446655440000',
loggingEnabled: false,
});
return () => subscription.remove();
}, []);
return null;
}
Register the listener before initialization so native success replay reaches JavaScript when ready. The public Project UUID belongs in app configuration; Organization API credentials remain server-side credentials.
Platform lifecycle ownership
Android
The native SDK owns cold and warm App Links. Do not read Linking.getInitialURL() and recreate it as an Intent. Keep the current Activity Intent updated:
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
}
iOS
Forward cold and warm URLs directly from AppDelegate/SceneDelegate to the native LimeLinkReactNative helper. Do not forward React Native Linking.getInitialURL() or JavaScript Linking events back into LimeLink.
import LimeLinkReactNative
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL else { return false }
return LimeLink.handleIncomingLink(url)
}
Call the same native helper from SceneDelegate cold/warm methods and app-owned custom-scheme callbacks.
LimeLink.handleIncomingLink(url) remains available in JavaScript only for a legitimate explicit app-owned handoff; it is not the normal iOS lifecycle integration mechanism.
Result contract
type LimeLinkResult = {
deeplinkUrl: string;
source: 'directDeepLink' | 'universalLink' | 'deferredDeepLink';
originalUrl: string | null;
isDeferred: boolean;
};
deeplinkUrl is the sole routing authority. Parse it and exactly compare its scheme and host to an app-owned allowlist before navigation.
Native SDKs own pre-initialization buffering, exact-URL five-second deduplication, and capacity-10 successful-result replay. The wrapper signals readiness when the first JS listener is present. Errors and deferred not-found outcomes are live-only.
Deferred deep links
const outcome = await LimeLink.handleDeferredDeepLink();
if (outcome.status === 'matched') {
if (isAllowedDestination(outcome.result.deeplinkUrl)) {
navigateTo(outcome.result.deeplinkUrl);
}
} else if (outcome.status === 'failed') {
showSafeFallback(outcome.error);
}
The status is exactly matched, notFound, or failed. Native listeners also receive manual outcomes, so choose either the Promise or listener as navigation owner. Malformed native outcomes and bridge failures can reject the Promise.
Public API
initialize(config: LimeLinkConfig): void
isInitialized(): boolean
addLinkListener(listener: LimeLinkListener): LimeLinkSubscription
handleIncomingLink(url: string): void
handleDeferredDeepLink(): Promise<DeferredDeepLinkOutcome>
Migrating from 0.1.1
- Replace removed
handleUniversalLink(url)withhandleIncomingLink(url)for explicit handoffs. - Replace
resolvedUriwith requireddeeplinkUrl. - Remove
queryParamsandpathParams; parsedeeplinkUrlas needed. - Handle required
sourceand nullableoriginalUrl. - Replace iOS React Native
Linkingforwarding with direct native lifecycle forwarding. - Remove JavaScript replay assumptions; native SDKs own success buffering and deduplication.
- Refresh native dependencies to
1.0.0and rebuild after npm and CocoaPods publication.