Installation
Add the Pulse React Native SDK to your project and initialize it.
Using Expo? See Expo Setup for automatic configuration via the plugin.
Requirements
- iOS 13.0+
- Android API 21+
Step 1 — Install the Package
yarn add @dreamhorizonorg/pulse-react-native
Native dependencies are linked automatically via React Native autolinking.
Step 2 — Native Initialization
The SDK must be initialized on the main thread, before React Native starts.
Android
Optional — minSdk below 26 (core library desugaring)
Only if minSdkVersion < 26. In android/app/build.gradle, enable desugaring under android { compileOptions { … } } and add the JDK libs artifact:
android {
compileOptions {
coreLibraryDesugaringEnabled true
}
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.4'
}
Background: Android library desugaring.
In MainApplication.kt, initialize before other setup:
import com.pulsereactnativeotel.Pulse
import com.pulsereactnativeotel.PulseDataCollectionConsent
class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
Pulse.initialize(
application = this,
apiKey = "your-api-key",
dataCollectionState = PulseDataCollectionConsent.ALLOWED
)
}
}
See Android APIs for native Android setup and links to the full initialize parameter list.
iOS
- Swift
- Objective-C
In AppDelegate.swift:
import PulseReactNativeOtel
@main
class AppDelegate: RCTAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
PulseSDK.initialize(
apiKey: "your-api-key",
dataCollectionState: .allowed
)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
See iOS APIs for native iOS options and all available initialize parameters.
In AppDelegate.m:
#import <PulseReactNativeOtel-Swift.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[PulseSDK pulseInitialize:@"your-api-key"
dataCollectionState:@"ALLOWED"
globalAttributes:nil
configuration:nil
instrumentations:nil];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
See iOS Obj-C APIs for all available options.
Step 3 — JS Initialization
In your app entry point (e.g. App.tsx), call Pulse.start() to enable JS-layer instrumentation:
import { Pulse } from '@dreamhorizonorg/pulse-react-native';
Pulse.start();
export default function App() {
// your app
}
What starts collecting immediately
With the basic setup above, the following works with no additional code:
- Crashes — native iOS/Android crashes and JS exceptions
- ANR detection (Android)
- App startup timing
- HTTP traffic — via
fetch/XMLHttpRequest/axios - Screen lifecycle (UIViewControllers / Activities)
- Session tracking
- Slow/Jank Frames (Android)
- Unhandled promise rejections
React Navigation screen tracking requires one extra step — see Navigation Instrumentation to connect the useNavigationTracking hook to your NavigationContainer.
Duplicate screen events: Native screen lifecycle (Fragment transitions on Android, UIViewController transitions on iOS) overlaps what React Navigation already records. Consider turning it off so you do not get the same screens twice:
Android (MainApplication.kt):
Pulse.initialize(...) {
fragment { enabled(false) }
// keep activity {} enabled — it powers the AppStart span
}
iOS — disable native screen lifecycle (Swift or Objective-C; ObjC):
- Swift
- Objective-C
PulseSDK.initialize(
apiKey: "...",
dataCollectionState: .allowed,
instrumentations: { config in
config.screenLifecycle { $0.enabled(false) }
}
)
PulseObjcInstrumentations *inst = [PulseObjcInstrumentations new];
inst.screenLifecycle = [PulseObjcEnabledConfig disabled];
[PulseSDK pulseInitialize:@"your-api-key"
dataCollectionState:@"ALLOWED"
globalAttributes:nil
configuration:nil
instrumentations:inst];
- Android: Built-in
Imageand libraries like FastImage use OkHttp, so those requests are not covered by JSfetch/XHR — use Android APIs to reach the OkHttp / network guide. - iOS: URLSession is tracked by default.
Step 4 — Verify
// App.tsx
if (Pulse.isInitialized()) {
console.log('Pulse is running');
}
You should see network requests and sessions appear in your Pulse dashboard within seconds of the first launch.
Next Steps
- Configuration — Tune JS instrumentation options (
autoDetectExceptions,autoDetectNetwork, etc.) - iOS APIs — Native iOS entry point and links to the full iOS reference
- Android APIs — Native Android entry point and links to the full Android reference