Skip to main content

Expo Setup

The Pulse config plugin automatically injects native initialization into your iOS and Android projects during expo prebuild — no manual AppDelegate or MainApplication edits needed.

Step 1 — Install

Use expo install so Expo can resolve compatible native versions:

npx expo install @dreamhorizonorg/pulse-react-native

Step 2 — Add Plugin to app.json

{
"expo": {
"plugins": [
[
"@dreamhorizonorg/pulse-react-native",
{
"endpointBaseUrl": "https://your-backend.com",
"apiKey": "your-api-key"
}
]
]
}
}

Step 3 — Start Pulse in JS

Call Pulse.start() at module scope in your root file so it runs before the rest of the app. In Expo Router, this is app/_layout.tsx:

import { Pulse } from '@dreamhorizonorg/pulse-react-native';

Pulse.start();

Step 4 — Run Prebuild

npx expo prebuild --clean
npx expo run:ios
# or
npx expo run:android

Re-run prebuild whenever you change the plugin config in app.json.

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 — native and fetch/XMLHttpRequest/axios
  • Screen lifecycle (UIViewControllers / Activities)
  • Session tracking
  • Slow/Jank frames (Android)
  • Unhandled promise rejections
note

React Navigation / Expo Router screen tracking requires one extra step. See Expo Router for Expo Router setup, or Navigation Instrumentation for bare React Navigation.

Greenfield Expo apps

Native screen lifecycle events (Fragment transitions on Android, UIViewController transitions on iOS) duplicate what Expo Router already tracks. Disable them via app.json to avoid noisy data:

{
"android": {
"instrumentation": {
"fragment": { "enabled": false }
}
},
"ios": {
"instrumentation": {
"screenLifecycle": { "enabled": false }
}
}
}

Keep activity enabled on Android — it powers the AppStart span.

Troubleshooting

IssueFix
Plugin error on prebuildEnsure endpointBaseUrl and apiKey are set at the top level; instrumentation, configuration, and globalAttributes must be inside android or ios — not at the root
iOS: Pulse not startingThe default Expo AppDelegate is patched automatically. If you have a custom entry point, call PulseSDK.initialize(...) manually before RN boots
Android: Pulse not startingSame — default MainApplication is patched. Custom entry → call Pulse.initialize(...) manually

Next Steps