Skip to main content

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

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.

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
note

React Navigation screen tracking requires one extra step — see Navigation Instrumentation to connect the useNavigationTracking hook to your NavigationContainer.

Greenfield React Native apps

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):

PulseSDK.initialize(
apiKey: "...",
dataCollectionState: .allowed,
instrumentations: { config in
config.screenLifecycle { $0.enabled(false) }
}
)

Image & FastImage Monitoring:

  • Android: Built-in Image and libraries like FastImage use OkHttp, so those requests are not covered by JS fetch/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