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

@targetprocess/react-tracing

v1.4.0

Published

React utilities for OpenTelemetry tracing

Readme

@targetprocess/react-tracing

React utilities for OpenTelemetry tracing.

Table of Contents

Installation

npm install @targetprocess/react-tracing @opentelemetry/api

Overview

This library provides React components, hooks, and utilities to easily add OpenTelemetry tracing to your React applications. It helps you monitor and analyze the performance of your React components and track user interactions.

Features

  • 🪝 React Hooks: Use the useSpan hook to create spans in functional components
  • 🧩 HOC Components: Wrap your components with withSpan to automatically trace rendering
  • 🌳 Context Providers: Configure tracing settings and propagate spans through your component tree

Quick Start

  1. Run OTEL exporter like Jaeger
podman run -d --name jaeger -p 16686:16686 -p 4317:4317 -p 4318:4318 -p 14250:14250 -p 14268:14268 -e COLLECTOR_OTLP_ENABLED=true -e COLLECTOR_OTLP_HTTP_HOST=0.0.0.0 -e COLLECTOR_OTLP_GRPC_HOST=0.0.0.0 -e COLLECTOR_OTLP_HTTP_CORS_ALLOWED_ORIGINS=* -e COLLECTOR_OTLP_GRPC_TLS_ENABLED=false jaegertracing/all-in-one:latest 
  1. Setup @opentelemetry
import {
    CompositePropagator,
    W3CBaggagePropagator,
    W3CTraceContextPropagator,
} from '@opentelemetry/core';
import {WebTracerProvider} from '@opentelemetry/sdk-trace-web';
import {BatchSpanProcessor} from '@opentelemetry/sdk-trace-base';
import {registerInstrumentations} from '@opentelemetry/instrumentation';
import {Resource, detectResourcesSync} from '@opentelemetry/resources';
import {browserDetector} from '@opentelemetry/opentelemetry-browser-detector';
import {ATTR_SERVICE_NAME} from '@opentelemetry/semantic-conventions';
import {OTLPTraceExporter} from '@opentelemetry/exporter-trace-otlp-http';

export const tracerName = 'my-app';

export const setup = () => {
    let resource = new Resource({
        [ATTR_SERVICE_NAME]: tracerName,
    });
    const detectedResources = detectResourcesSync({
        detectors: [browserDetector as any],
    });
    resource = resource.merge(detectedResources);
    const OTLPProxyUrl = 'http://localhost:4318/v1/traces';

    const provider = new WebTracerProvider({
        resource,
        spanProcessors: [
            new BatchSpanProcessor(
                new OTLPTraceExporter({
                    url: OTLPProxyUrl,
                }) as any,
                {
                    scheduledDelayMillis: 500,
                },
            ),
        ],
    });

    provider.register({
        propagator: new CompositePropagator({
            propagators: [
                new W3CBaggagePropagator(),
                new W3CTraceContextPropagator(),
            ],
        }),
    });

    registerInstrumentations({
        tracerProvider: provider,
    });
};
  1. Wrap app with tracer
import { TelemetrySettingsProvider, withSpan, useSpan, useSpanFactory } from '@targetprocess/react-tracing';
import { setup, tracerName } from './tracer';

// Init @opentelemetry tracer
setup()

// Use the withSpan HOC to automatically trace component rendering
const TracedComponent = withSpan()(MyComponent);

// Configure telemetry settings at the app root
function App() {
  return (
    <TelemetrySettingsProvider settings={{ 
      tracerName,
      sharedAttributes: {
        environment: process.env.NODE_ENV,
        version: '1.0.0'
      }
    }}>
      <MyComponent />
    </TelemetrySettingsProvider>
  );
}

// Or use the useSpan hook for more control
function MyComponent() {
  const { span } = useSpan('MyComponent');
  const { startSpan } = useSpanFactory();

  useEffect(() => {
    // Create a child span for a specific operation
    const childSpan = startSpan('DataFetching');
    fetchData().then(() => {
      childSpan?.end();
    });
  }, []);

  return <div>My Component</div>;
}

API Reference

Hooks

useSpan

A React hook that creates an OpenTelemetry span for a component or custom logic. The span is created when the component mounts and can be used throughout the component's lifecycle.

import { useSpan } from '@targetprocess/react-tracing';

function MyComponent() {
  const { span } = useSpan('MyComponent');

  // Use the span
  useEffect(() => {
    // Add attributes to the span
    if (span) {
      span.setAttribute('component.type', 'functional');
    }

    return () => {
      // End the span when component unmounts
      if (span) span.end();
    };
  }, []);

  return <div>My Component</div>;
}

Parameters:

  • name: string - The name of the span
  • options?: ReactSpanOptions - Optional OpenTelemetry span options with additional React-specific options
    • skipDefaultAttributes?: boolean - When true, shared attributes from TelemetrySettingsProvider will not be applied to this span

Returns:

  • span: Span | null - The created OpenTelemetry span, or null if telemetry is disabled

useSpanFactory

A React hook that provides a factory function for creating multiple spans on demand. This is useful when you need to create spans for specific operations within a component.

import { useSpanFactory } from '@targetprocess/react-tracing';

function MyComponent() {
  const { startSpan } = useSpanFactory();

  const handleClick = async () => {
    // Create a span for this specific operation
    const span = startSpan('button.click');

    try {
      // Add attributes to the span
      span?.setAttribute('button.id', 'submit-button');

      await performOperation();

      // End the span when the operation is complete
      span?.end();
    } catch (error) {
      // Record the error on the span
      span?.recordException(error);
      span?.end();
      throw error;
    }
  };

  const handleCustomClick = async () => {
    // Create a span without shared attributes
    const span = startSpan('custom.operation', {
      skipDefaultAttributes: true,
      attributes: {
        custom: 'value',
        operation: 'special'
      }
    });

    try {
      await performCustomOperation();
      span?.end();
    } catch (error) {
      span?.recordException(error);
      span?.end();
      throw error;
    }
  };

  return (
    <div>
      <button onClick={handleClick}>Click Me</button>
      <button onClick={handleCustomClick}>Custom Operation</button>
    </div>
  );
}

Parameters:

  • parentSpan?: Span - Optional parent span to use instead of the span from context

Returns:

  • startSpan: (name: string, options?: ReactSpanOptions) => Span | null - Function to create a new span
    • options.skipDefaultAttributes?: boolean - When true, shared attributes from TelemetrySettingsProvider will not be applied to this span

Components

withSpan

A higher-order component (HOC) that wraps a component with OpenTelemetry tracing. It automatically creates a span when the component mounts and ends it when the component unmounts.

import { withSpan } from '@targetprocess/react-tracing';

function MyComponent(props) {
  return <div>My Component</div>;
}

// Basic usage with default options
export default withSpan()(MyComponent);

// With custom span name and options
export default withSpan({
  name: 'CustomSpanName',
  options: {
    attributes: {
      'component.important': true,
    },
  },
})(MyComponent);

Parameters:

  • spanOptions?: WithSpanOptions - Optional configuration
    • name?: string - Custom span name (defaults to component name)
    • options?: ReactSpanOptions - OpenTelemetry span options with additional React-specific options
      • skipDefaultAttributes?: boolean - When true, shared attributes from TelemetrySettingsProvider will not be applied to this span

ErrorBoundary

A React component that catches errors in its child components and records them as OpenTelemetry spans. This helps track and monitor errors in your React application.

import { ErrorBoundary } from '@targetprocess/react-tracing';

function App() {
  return (
    <ErrorBoundary>
      <YourComponent />
    </ErrorBoundary>
  );
}

// With rethrow option
function AppWithRethrow() {
  return (
    <ErrorBoundary rethrow={true}>
      <YourComponent />
    </ErrorBoundary>
  );
}

Props:

  • children: ReactNode - Child components to render
  • rethrow?: boolean - When true, the error will be re-thrown after recording it in the span. This allows parent error boundaries to catch the error. Defaults to false.

Context Providers

TelemetrySettingsProvider

A context provider for configuring telemetry settings across your application.

import { TelemetrySettingsProvider } from '@targetprocess/react-tracing';

function App() {
  const settings = {
    tracerName: 'my-app-tracer',
    disabled: process.env.NODE_ENV === 'development',
    sharedAttributes: {
      environment: process.env.NODE_ENV,
      version: '1.0.0',
      region: 'us-east-1'
    }
  };

  return (
    <TelemetrySettingsProvider settings={settings}>
      <AppContent />
    </TelemetrySettingsProvider>
  );
}

Props:

  • settings: ContextInitialState - Configuration options for the telemetry system
    • tracerName: string - Name of the OpenTelemetry tracer to use
    • disabled?: boolean - Whether telemetry is disabled
    • sharedAttributes?: Attributes - Attributes that will be added to every span in the React tree

ParentSpanContextProvider

A context provider that makes a span available to child components. This is used internally by the withSpan HOC but can also be used directly when needed.

import { ParentSpanContextProvider } from '@targetprocess/react-tracing';
import { trace } from '@opentelemetry/api';

function MyComponent() {
  // Create a span
  const span = trace.getTracer('my-tracer').startSpan('my-operation');
  
  return (
    <ParentSpanContextProvider span={span}>
      {/* Child components can access this span via useSpanContext */}
      <ChildComponent />
    </ParentSpanContextProvider>
  );
}

Props:

  • span: Span | null - The span to make available to child components
  • children: ReactNode - Child components

Context Hooks

useSpanContext

A hook that provides access to the parent span from the nearest ParentSpanContextProvider.

import { useSpanContext } from '@targetprocess/react-tracing';
import { trace } from '@opentelemetry/api';

function ChildComponent() {
  const { parentSpan, getParentContext } = useSpanContext();
  
  // Use the parent span
  useEffect(() => {
    if (parentSpan) {
      // Access the parent span directly
      parentSpan.setAttribute('child.mounted', true);
      
      // Or use the parent context to create a child span
      const ctx = getParentContext();
      const tracer = trace.getTracer('my-tracer');
      const childSpan = tracer.startSpan('child-operation', {}, ctx);
      
      // Do something with the child span
      childSpan.end();
    }
  }, []);
  
  return <div>Child Component</div>;
}

Returns:

  • parentSpan: Span | null - The parent span from context, or null if not available
  • getParentContext: () => Context - Function that returns the active context with the parent span set

Redux Tools

Trace Middleware

The trace middleware connects your Redux store to the span tracing system, automatically forwarding actions to the SpanFlowControl.

import { createTraceMiddleware } from '@targetprocess/react-tracing';
import { configureStore } from '@reduxjs/toolkit';
import { trace } from '@opentelemetry/api';

// Define your flows
const flows = new Map();
flows.set('userAuthentication', {
  startEvents: new Set(['USER_LOGIN_REQUEST']),
  endEvents: new Set(['USER_LOGIN_SUCCESS']),
  errorEvents: new Set(['USER_LOGIN_FAILURE']),
  // SequenceTelemetryOptions for customizing span creation
  getParentSpan: () => parentSpan, // Optional function to provide a parent span
  spanOptions: {                   // Optional OpenTelemetry SpanOptions
    attributes: {
      'flow.type': 'authentication',
      'user.role': 'customer'
    }
  }
});

// Create the middleware
const tracer = trace.getTracer('my-app');
const traceMiddleware = createTraceMiddleware(flows, tracer);

// Add to your Redux store
const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) => 
    getDefaultMiddleware().concat(traceMiddleware),
});

SequenceTelemetryOptions

When defining flows for SpanFlowControl, you can include additional telemetry options to customize how spans are created:

  • getParentSpan: () => Span | undefined A function that returns a parent span to establish parent-child relationships between spans. This allows you to create hierarchical traces.
  • spanOptions: SpanOptions Standard OpenTelemetry SpanOptions that will be applied to the created span. This can include attributes, links, and other span configuration. Example:
 flows.set('checkout', {
   startEvents: new Set(['CHECKOUT_START']),
   endEvents: new Set(['CHECKOUT_COMPLETE']),
   subEvents: new Set(['PAYMENT_PROCESSING', 'INVENTORY_CHECK']),
   errorEvents: new Set(['CHECKOUT_ERROR']),
   // Telemetry options
   getParentSpan: () => currentTransactionSpan,
   spanOptions: {
     attributes: {
       'transaction.type': 'purchase',
       'transaction.amount': '125.50',
       'customer.type': 'returning'
     }
   }
 });

SpanFlowControl

The SpanFlowControl is the core engine behind the trace middleware. It manages event sequences and creates spans based on defined flows. You can use it directly for more advanced use cases:

  import { SpanFlowControl } from '@targetprocess/react-tracing';
 
  // Define your flows
  const flows = new Map();
  flows.set('userSession', {
    startEvents: new Set(['USER_LOGIN']),
    endEvents: new Set(['USER_LOGOUT']),
    subEvents: new Set(['USER_UPDATE_PROFILE', 'USER_CHANGE_PASSWORD']),
    errorEvents: new Set(['USER_SESSION_ERROR']),
  });
 
  // Create the flow control
  const flowControl = new SpanFlowControl(flows, 'my-app-tracer');
 
  // Handle events manually
  flowControl.handleEvent('USER_LOGIN');
  flowControl.handleEvent('USER_UPDATE_PROFILE');
  flowControl.handleEvent('USER_LOGOUT');

The SpanFlowControl uses a state machine internally to track event sequences and automatically creates spans with appropriate timing information. When a flow completes (or encounters an error), it creates a span that includes:

  1. All events in the sequence as span events
  2. Error events recorded as exceptions
  3. Accurate timing information for the entire flow
  4. Custom attributes from spanOptions

This is particularly useful for tracking user journeys, multi-step processes, or any sequence of events that should be traced as a single logical operation.

The SpanFlowControl can handle multiple flows simultaneously, making it ideal for complex applications with overlapping user interactions or system processes.