Schedule demo

Mobile App Monitoring for React Native


Applications Manager Mobile App Monitor for React Native lets you measure the performance and stability of React Native applications on end-user devices. The React Native SDK captures screen, network, transaction, error, crash, and application-not-responding (ANR) data for analysis in Applications Manager.

This page explains how to install the react-native-memobileapminsight-rn package, configure the native Android and iOS projects, initialize monitoring, and instrument common application workflows.

Browse through the following topics to learn more about configuring Mobile App Monitor for React Native:

Prerequisites

Requirement Version or requirement
react 18.2.0 or later
react-native 0.71.0 or later and earlier than 1.0.0
iOS Deployment target 15.0 or later
Android Compile SDK API 21 or later, Java 1.8 or later, and AndroidX enabled with android.useAndroidX=true in gradle.properties.
apm_config.json Download from a Mobile App Monitor created in Applications Manager and place it in the Android project.
apm_config.plist Download from a Mobile App Monitor created in Applications Manager and add it to the iOS project.

Install the package

The package is hosted on a CDN registry. Install it with the --registry flag:

npm install react-native-memobileapminsight-rn --registry=https://static.zohocdn.com/memobileapminsight-reactnativesdk --legacy-peer-deps

Autolinking links the native module automatically. No manual linking step is required.

Platform setup

Android

Add the ManageEngine Maven repository to android/build.gradle:

buildscript {
    repositories {
        maven { url 'https://maven.zohodl.com' }
    }
}

allprojects {
    repositories {
        maven { url 'https://maven.zohodl.com' }
    }
}

Sync Gradle from Android Studio, or run ./gradlew build once, to confirm that the package resolves.

Download apm_config.json from the Mobile App Monitor installation and place it at android/app/src/main/res/raw/apm_config.json. The file is prefilled with the appKey, collectorURL, uploadInterval, and payloadSize values.

Note: If the collector endpoint uses a self-signed certificate in a debug or evaluation environment, add the apm_cert.cer file (from the DEM Collector installation directory /conf/sslcerts) alongside apm_config.json in android/app/src/main/res/raw/. Self-signed certificates are not recommended for production.

iOS

Open the Podfile at <your-project>/ios/Podfile and add the following line inside your application target:

pod 'react-native-memobileapminsight-rn', :path => '../node_modules/react-native-memobileapminsight-rn'

For example:

target 'YourAppName' do
  # ... other pods
  pod 'react-native-memobileapminsight-rn', :path => '../node_modules/react-native-memobileapminsight-rn'
end

Navigate to the ios folder and run:

pod install

After pod install completes, open the .xcworkspace file, not the .xcodeproj file.

Drag apm_config.plist into the root of the Xcode project. In the dialog that appears, set Action to Copy files to destination, select the required application target, and click Finish.

Note: If the collector endpoint uses a self-signed certificate in a debug or evaluation environment, add the apm_cert.cer file (from the DEM Collector installation directory /conf/sslcerts) to the Xcode project alongside apm_config.plist, using the same Copy files to destination option. Self-signed certificates are not recommended for production.

When using a self-signed certificate, you must allow an exception in Info.plist for the DEM collector domain. Open Info.plist and add the following configuration:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>[collectordomain].com</key>
    <dict>
      <key>NSExceptionAllowsInsecureHTTPLoads</key>
      <true/>
    </dict>
  </dict>
</dict>

Replace [collectordomain].com with your DEM collector domain.

Initialize monitoring

Import the module once in the application entry point, such as App.js or App.tsx, before making other SDK calls:

import { mobileapm } from 'react-native-memobileapminsight-rn';

Start monitoring as early as possible in the application lifecycle. You can pass native screen names to exclude from automatic tracking:

mobileapm.startMonitoring(['SplashScreen']); // optional screens to ignore

Call startMonitoring exactly once. Other tracking calls are no-ops until monitoring starts.

To enable verbose SDK logs during integration, disable them in production builds:

mobileapm.setDebugLoggingEnabled(__DEV__);

__DEV__ is React Native's built-in Boolean global. It is true in debug builds and false in release builds.

Enable network monitoring

Pass an array of URL substrings to exclude from tracking, such as development-server or internal endpoints. Call this immediately after startMonitoring:

mobileapm.initializeNetworkMonitoring(['/symbolicate', '/ping']);

Enable error and crash monitoring

Configure the JavaScript, native, console, and unhandled-rejection error sources you want to track:

mobileapm.initializeErrorMonitoring({
  trackUnhandledErrors: true,
  trackConsoleErrors: false,
  trackUnhandledRejections: true,
  trackNativeErrors: false
});

Call this once after monitoring has started and before rendering the rest of the application.

Manual exception capture

Wrap risky code and report caught exceptions explicitly:

try {
  riskyOperation();
} catch (err) {
  mobileapm.captureException(err);
}

Error boundary for render errors

Wrap a subtree so render and lifecycle errors are reported with a fallback user interface. The fallback value must be a function component:

const FallbackComponent = () => (
  <View>
    <Text>Something went wrong</Text>
  </View>
);

<mobileapm.ErrorBoundary fallback={FallbackComponent}>
  <YourScreenComponent />
</mobileapm.ErrorBoundary>

ANR reporting

Enable ANR reporting with the default threshold, or provide a custom threshold in seconds:

mobileapm.enableANRReporting();

// or with a custom threshold in seconds
mobileapm.enableANRReportingWithThreshold(5);

// disable later if needed
mobileapm.disableANRReporting();

Test crashes

Use these methods only to verify crash and ANR reporting during integration. Do not expose them through production code paths:

mobileapm.crashApplication(); // throws a JS error
mobileapm.crashNative();      // triggers a native crash
mobileapm.triggerANRForTesting(6); // simulates an ANR

Screen tracking

Screen data supports session tracking, crash context, and performance analysis. Choose one of the following approaches and use it consistently:

  • Option A: Use enableReactNavigation(ref) with React Navigation or Expo Router.
  • Option B: Replace NavigationContainer with MEAPMNavigationContainer.
  • Option C: Use enableReactNativeNavigation(Navigation) with Wix React Native Navigation.
  • Option D: Use beginScreen and endScreen for custom navigation or explicit per-screen control.

Options A, B, and C capture frame rate, screen duration, and total, slow, and frozen frame counts without per-screen code.

Option A - Automatic: enableReactNavigation(ref)

This option is recommended for apps using @react-navigation/native or Expo Router. It attaches listeners to a navigation container reference without changing the NavigationContainer component:

import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
import { mobileapm } from 'react-native-memobileapminsight-rn';
import { useEffect } from 'react';

export default function App() {
  const navigationRef = useNavigationContainerRef();

  useEffect(() => {
    // Returns unsubscribe - React cleans it up automatically.
    return mobileapm.enableReactNavigation(navigationRef);
  }, []);

  return (
    <NavigationContainer ref={navigationRef}>
      { /* your navigator */ }
    </NavigationContainer>
  );
}

Every screen in every navigator, including nested stacks inside tabs and drawers, is tracked automatically.

Option B - Automatic: MEAPMNavigationContainer

This drop-in replacement for React Navigation's NavigationContainer tracks route changes automatically and forwards the container props:

import { MEAPMNavigationContainer } from 'react-native-memobileapminsight-rn';

export default function App() {
  return (
    <MEAPMNavigationContainer>
      { /* your navigator */ }
    </MEAPMNavigationContainer>
  );
}

Every screen in every navigator is tracked automatically.

Option C - Automatic: enableReactNativeNavigation(Navigation)

Use this option with Wix React Native Navigation. It subscribes to componentDidAppear and componentDidDisappear events and calls beginScreen and endScreen for each transition:

import { Navigation } from 'react-native-navigation';
import { mobileapm } from 'react-native-memobileapminsight-rn';

mobileapm.startMonitoring();
mobileapm.enableReactNativeNavigation(Navigation);

Navigation.registerComponent('Home', () => HomeScreen);
Navigation.registerComponent('Profile', () => ProfileScreen);

Navigation.events().registerAppLaunchedListener(() => {
  Navigation.setRoot({ root: { bottomTabs: { children: [
    { component: { name: 'Home' } },
    { component: { name: 'Profile' } }
  ] } } });
});

To exclude overlays or modals, pass their registered component names in ignoredComponents:

mobileapm.enableReactNativeNavigation(Navigation, {
  ignoredComponents: ['LoadingOverlay', 'ToastNotification']
});

Option D - Manual: beginScreen and endScreen

Use this option for custom navigation or explicit per-screen control. With React Navigation, use useFocusEffect instead of useEffect so back navigation is tracked:

import { useFocusEffect } from '@react-navigation/native';
import { useCallback, useRef } from 'react';

function HomeScreen() {
  const mountedAt = useRef(Date.now());

  useFocusEffect(
    useCallback(() => {
      mobileapm.beginScreen('Home', Date.now() - mountedAt.current);
      return () => {
        mobileapm.endScreen('Home');
        mountedAt.current = Date.now(); // reset for next focus
      };
    }, [])
  );

  return <View>...</View>;
}

For custom or no navigation, use useEffect with an empty dependency array:

function HomeScreen() {
  const mountedAt = useRef(Date.now());

  useEffect(() => {
    mobileapm.beginScreen('Home', Date.now() - mountedAt.current);
    return () => mobileapm.endScreen('Home');
  }, []);

  return <View>...</View>;
}

For class components, call beginScreen in componentDidMount and endScreen in componentWillUnmount. To exclude native screens such as a splash screen from automatic tracking, use:

mobileapm.excludeNativeScreens(['SplashScreen']);

User and environment tagging

Set the user identifier and environment as soon as they are known, such as after login or at application startup:

mobileapm.setUserId('user@example.com'); // omit to use an auto-generated GUID
mobileapm.setEnvironment('production'); // e.g. production | staging | qa

Use an opaque identifier instead of raw personally identifiable information when your application requires a user identifier.

Custom transactions and components

Use transactions to time a logical unit of work and components to break it down further:

mobileapm.startTransaction('listing_blogs');
mobileapm.startComponent('listing_blogs', 'http_request');
await fetchBlogs();
mobileapm.stopComponent('listing_blogs', 'http_request');

mobileapm.startComponent('listing_blogs', 'view_data_onto_screen');
renderBlogs();
mobileapm.stopComponent('listing_blogs', 'view_data_onto_screen');

mobileapm.stopTransaction('listing_blogs');

Follow these rules:

  • txnName and componentName must be non-empty strings.
  • Every startTransaction call must have a matching stopTransaction call.
  • Start and stop components within the same transaction name.

Breadcrumbs

Add manual breadcrumbs to provide context leading up to an error:

mobileapm.addBreadCrumb('Info', 'download completed');

Flushing data

Data uploads automatically according to uploadInterval. To force an immediate upload, for example before application termination, use:

mobileapm.flush();

Stop monitoring

Use this method sparingly, such as in a user opt-out flow:

mobileapm.stopMonitoring();

Recommended integration order

Call the SDK methods from the application entry point in the following order:

  1. Import mobileapm and enable debug logging only for development builds.
  2. Start monitoring with the configuration downloaded from Applications Manager.
  3. Initialize network monitoring with the URL substrings to ignore.
  4. Initialize error monitoring with the required error flags.
  5. Set the user identifier and environment when they become available.
  6. Wrap the root component with mobileapm.ErrorBoundary when render-error reporting is required.
  7. Configure screen tracking for the navigation library used by the application.
import { mobileapm } from 'react-native-memobileapminsight-rn';

mobileapm.setDebugLoggingEnabled(__DEV__);
mobileapm.startMonitoring();
mobileapm.initializeNetworkMonitoring(['/symbolicate']);
mobileapm.initializeErrorMonitoring({
  trackUnhandledErrors: true,
  trackUnhandledRejections: true
});
mobileapm.setEnvironment(__DEV__ ? 'staging' : 'production');

Verification checklist

  • Confirm that the application builds and runs on Android and iOS after the Maven and Podfile changes.
  • Confirm that setDebugLoggingEnabled(true) shows SDK logs during a debug session. Remove or guard this setting for release builds.
  • Navigate between screens and confirm that screen-tracking calls appear in the logs or dashboard.
  • Make a test network call and confirm that it appears in the network monitoring dashboard.
  • Use crashApplication() temporarily from a development-only control to produce a crash report.
  • Call mobileapm.flush() and confirm that buffered data appears on the dashboard.

Full API reference

The following tables summarize the React Native SDK methods and their parameters.

Monitoring and configuration

Method Parameter types Description
setDebugLoggingEnabled(enabled)enabled: boolean Toggle verbose SDK logging.
startMonitoring(ignoredScreens?)ignoredScreens?: string[] Start monitoring using the native configuration.
stopMonitoring() - Stop monitoring.
initializeNetworkMonitoring(ignoredHttpCalls?)ignoredHttpCalls?: string[] Enable HTTP call tracking and optionally ignore URL substrings.
initializeErrorMonitoring(config)config: ErrorMonitoringConfig Enable JavaScript and native error tracking.
setUserId(userId)userId: string Associate telemetry with a user.
setEnvironment(env)env: string Tag telemetry with an environment name.

Screen and error handling

Method Parameter types Description
enableReactNavigation(navigationRef)navigationRef: NavigationContainerRef Auto-track every route change via a React Navigation container ref (Option A).
MEAPMNavigationContainer
import { MEAPMNavigationContainer } from 'react-native-memobileapminsight-rn';
Accepts and forwards every NavigationContainer prop, including ref Drop-in replacement for NavigationContainer that auto-tracks every route change (Option B).
enableReactNativeNavigation(Navigation, options?)Navigation: Navigation, options?: { ignoredComponents?: string[] } Auto-track Wix React Native Navigation screen transitions (Option C).
beginScreen(screenName, loadTime)screenName: string, loadTime: number Start tracking a screen. Must be paired with endScreen (Option D).
endScreen(screenName)screenName: string End tracking and send the screen's metrics. The name must match the beginScreen call (Option D).
addScreen(screenName, loadTime)screenName: string, loadTime: number Report a screen view and load time.
excludeNativeScreens(screenNames)screenNames: string[] Exclude native screens from tracking.
ErrorBoundaryfallback: React.ComponentType Wrap a React subtree with a fallback component for render errors.
captureException(err)err: Error Manually report a caught exception.
addBreadCrumb(event, message)event: string, message: string Add a manual breadcrumb.
enableANRReporting() / enableANRReportingWithThreshold(seconds) / disableANRReporting()seconds: number for threshold Control ANR reporting.

Transactions and data controls

Method Parameter types Description
startTransaction(txnName) / stopTransaction(txnName)txnName: string Track a custom transaction.
startComponent(txnName, componentName) / stopComponent(txnName, componentName)txnName: string, componentName: string Group work within a transaction.
flush() - Force an immediate upload.
crashApplication() / crashNative() / triggerANRForTesting(seconds)seconds: number for ANR testing Trigger test crashes or an ANR during integration testing only.

Troubleshooting

  • Tracking calls such as addScreen, startTransaction, or setUserId have no effect: These APIs may have been called before startMonitoring or before the initialization calls completed. Start monitoring first and initialize the remaining modules afterward.
  • ErrorBoundary does not display the fallback user interface: Ensure that the fallback property is a function component. Do not pass a class component or a hook-based component directly as the fallback.
  • The native build fails or the native module is unavailable at runtime: Verify that the Maven repository entry for Android or the Podfile entry for iOS is present, then repeat the platform setup steps.
  • Users unexpectedly experience crashes or ANRs in production: Remove test methods such as crashApplication(), crashNative(), and triggerANRForTesting() from production code paths. Disable debug logging in release builds.

Loved by customers all over the world

"Standout Tool With Extensive Monitoring Capabilities"

★★★★★

It allows us to track crucial metrics such as response times, resource utilization, error rates, and transaction performance. The real-time monitoring alerts promptly notify us of any issues or anomalies, enabling us to take immediate action.

Reviewer Role: Research and Development

carlos-rivero
"I like Applications Manager because it helps us to detect issues present in our servers and SQL databases."
Carlos Rivero

Tech Support Manager, Lexmark

Trusted by thousands of leading businesses globally