npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@embrace-io/react-native-navigation

v6.7.0

Published

A React Native wrapper for the OTel Navigation instrumentation library that creates telemetry data representing Navigation changes

Readme

React Native Embrace - Navigation

[!IMPORTANT]

This module requires both the React Native Embrace SDK and the React Native Embrace Tracer Provider.

This package uses Embrace's React Native SDK and OpenTelemetry Tracer Provider to collect telemetry around Navigation based on expo-router, @react-navigation/native and react-native-navigation.

Install the component

npm:

npm install @embrace-io/react-native-navigation

yarn:

yarn add @embrace-io/react-native-navigation

Setup in your code

Using expo-router:

import React from 'react';
import {useEmbraceNativeTracerProvider} from "@embrace-io/react-native-tracer-provider";
import {EmbraceNavigationTracker} from "@embrace-io/react-native-navigation";
import {Stack, useNavigationContainerRef} from 'expo-router';
import {useEmbrace} from "@embrace-io/react-native";

const App = () => {
  const {isStarted} = useEmbrace({
    ios: {
      appId: "__APP_ID__"
    }
  });

  // The provider is something you need to configure and pass down as prop into the `<EmbraceNavigationTracker />` component 
  // If your choice is not to pass any custom tracer provider, the component will use the global one.
  // In both cases you have to make sure a tracer provider is registered BEFORE you attempt to record the first span (otherwise some initial telemetry can be missed).
  const {tracerProvider, isLoading: isLoadingTracerProvider} =
    useEmbraceNativeTracerProvider({}, isStarted);

  // If you do not use `expo-router` the same hook is also available in `@react-navigation/native` since `expo-router` is built on top of it.
  // Make sure this ref is passed also to the navigation container at the root of your app (if not, the ref would be empty and you will get a console.warn message instead).
  const expoNavigationRef = useNavigationContainerRef();

  if (isLoadingTracerProvider || tracerProvider === null) {
    return (
      <View>
        <View>
          <Text>Loading Tracer Provider...</Text>
        </View>
      </View>
    );
  }

  return (
    <EmbraceNavigationTracker
      ref={expoNavigationRef}
      tracerProvider={tracerProvider}
      // These static attributes will be passed into each created span
      screenAttributes={{
          "static.attribute": 123456,
          "custom.key": "abcd...",
      }}>
      <Stack>
        <Stack.Screen name="(tabs)" options={{headerShown: false}} />
        <Stack.Screen name="+not-found" />
        ... rest of stack
      </Stack>
    </EmbraceNavigationTracker>
  );
};

export default App;

If you are using purely @react-navigation/native:

import React from 'react';
import {useEmbraceNativeTracerProvider} from "@embrace-io/react-native-tracer-provider";
import {EmbraceNavigationTracker} from "@embrace-io/react-native-navigation";
import {
  NavigationContainer,
  useNavigationContainerRef,
} from "@react-navigation/native";
import {createBottomTabNavigator} from "@react-navigation/bottom-tabs";
import {useEmbrace} from "@embrace-io/react-native";
import CartPage from "screens/CartPage";
import CheckoutPage from "screens/CheckoutPage";

const Tab = createBottomTabNavigator();

const App = () => {
  const {isStarted} = useEmbrace({
    ios: {
      appId: "__APP_ID__"
    }
  });

  // The provider is something you need to configure and pass down as prop into the `EmbraceNavigationTracker` component 
  // If your choice is not to pass any custom tracer provider, the <EmbraceNavigationTracker /> component will use the global one.
  // In both cases you have to make sure a tracer provider is registered BEFORE you attempt to record the first span.
  const {tracerProvider, isLoading: isLoadingTracerProvider} =
    useEmbraceNativeTracerProvider({}, isStarted);

  // Tip! as of now if you inspect the source code of `useNavigationContainerRef` from `@react-navigation/native` you will see that it returns `navigation.current` instead of the entire shape of a reference
  const navigationRefVal = useNavigationContainerRef();
  // We need here the entire shape, so we re-create it and pass it down into the `ref` prop for the `EmbraceNavigationTracker` component.
  const navigationRef = useRef(navigationRefVal);

  if (isLoadingTracerProvider || tracerProvider === null) {
    return (
      <View>
        <View>
          <Text>Loading Tracer Provider...</Text>
        </View>
      </View>
    );
  }

  return (
    // `NavigationContainer` is waiting for what `useNavigationContainerRef` is returning (both exported from `@react-navigation/native`)
    <NavigationContainer ref={navigationRefVal}>
      <EmbraceNavigationTracker
        ref={navigationRef}
        tracerProvider={tracerProvider}
        screenAttributes={{
          "static.attribute": 123456,
          "custom.key": "abcd...",
        }}>
        <Tab.Navigator
          screenOptions={{
            tabBarLabelPosition: "beside-icon",
            tabBarIconStyle: {display: "none"},
          }}>
          <Tab.Screen
            name="cart"
            options={{
              tabBarAccessibilityLabel: "Cart",
            }}
            component={CartPage}
          />
          <Tab.Screen
            name="checkout"
            options={{
              tabBarAccessibilityLabel: "Checkout",
            }}
            component={CheckoutPage}
          />
          ... rest of tabs
        </Tab.Navigator>
      </EmbraceNavigationTracker>
    </NavigationContainer>
  );
};

export default App;

NOTE: If you are using @react-navigation/native you need to wrap your entire application with the NavigationTracker component as described in their official documentation.

If you are using react-native-navigation you are also able to track navigation changes. You have to make sure you wrap your entry view with the <EmbraceNativeNavigationTracker /> component and initialize Embrace as soon as possible to avoid missing telemetry data.

// index.ts
import React, {useRef} from "react";
import {EmbraceNativeTracerProvider} from "@embrace-io/react-native-tracer-provider";
import {TracerProvider} from "@opentelemetry/api";
import {EmbraceNativeNavigationTracker} from "@embrace-io/react-native-navigation";
import {initialize} from "@embrace-io/react-native";
import {Navigation} from "react-native-navigation";
import {HomeScreen} from "screens/HomeScreen";

const initApp = async () => {
  // this example is showing how we can initialize Embrace not using hooks
  await initialize({
    sdkConfig: {
      ios: {appId: "__APP_ID__"},
    },
  });

  let embraceTracerProvider: TracerProvider;
  try {
    embraceTracerProvider = new EmbraceNativeTracerProvider();
  } catch (e) {
    console.log(
      "Error creating `EmbraceNativeTracerProvider`. Will use global tracer provider instead",
      e,
    );
  }

  Navigation.registerComponent(
    "HomeScreen",
    () =>
      (props) => {
        // make sure to wrap the events registry instance in a React ref
        const navRef = useRef(Navigation.events());

        return (
          <EmbraceNativeNavigationTracker
            ref={navRef}
            tracerProvider={embraceTracerProvider}
            screenAttributes={{
              "test.attr": 98765,
              dev: true,
            }}>
            <HomeScreen {...props} />
          </EmbraceNativeNavigationTracker>
        );
      },
    () => HomeScreen,
  );

  // ... rest of registration and configuration
};

// root of the app
initApp();

Disable Auto Tracking for Native Screens

Embrace also collects automatically the Native screens, if you do not want to see Native components in the Session you can disable it:

JavaScript

const App = () => {
  const {isPending, isStarted} = useEmbrace({
    ios: {
      appId: "__APP_ID__",
      disableAutomaticViewCapture: true, // disabling the feature just for iOS
    },
  });


  if (isPending) {
    return (
      <View>
        <Text>Loading Embrace</Text>
      </View>
    );
  } else {
    if (!isStarted) {
      console.log('An error occurred during Embrace initialization');
    }
  }

  // regular content of the application
  return (
    ...  
  );
}

export default App

Android

Go to your embrace-config.json inside android/app/src/main and edit the sdk_config key. With these changes your file should at least look like the following:

{
  "app_id": "APP_ID",
  "api_token": "API_TOKEN",
  "sdk_config": {
    "app_framework": "react_native",
    "view_config": {
      "enable_automatic_activity_capture": false // disabling automatic capture
    }
  }
}

iOS:

If you used the automated installation script or followed the manual steps for setting up the iOS SDK then you can modify the setup in EmbraceInitializer.swift to remove the view capture service, see Configurating the iOS SDK for more details:

import Foundation
import EmbraceIO
import EmbraceCrash

@objcMembers class EmbraceInitializer: NSObject {
    static func start() -> Void {
        do {
         
            try Embrace
                .setup(
                    options: Embrace.Options(
                        appId: "__APP_ID__",
                        platform: .reactNative,
                        captureServices: CaptureServiceBuilder()
                            .addDefaults()
                            .remove(ofType: ViewCaptureService.self)
                            .build(),
                        crashReporter: EmbraceCrashReporter()
                    )
                )
                .start()
        } catch let e {
            print("Error starting Embrace \(e.localizedDescription)")
        }
    }
}