The Multiplayer Session Recorder for React Native provides comprehensive session recording capabilities for React Native applications, including gesture tracking, navigation monitoring, screen recording, and full-stack debugging. It includes full support for both bare React Native and Expo applications.
⚠️ Important: Web Platform Limitations
This package does NOT support React Native Web. The session recorder relies on native modules for core functionality:
- Screen Recording: Requires native screen capture capabilities - Gesture Recording: Uses native gesture detection systems - Native Module Dependencies: Core features depend on iOS/Android native modules
If you need web support, consider using the browser-specific session recorder package instead.
Recommended: Initialize with SessionRecorder.init(options) before you mount your React Native app to avoid losing any data (similar to Sentry's guidance).
$3
This package requires the following dependencies to be installed in your React Native application:
Important: Native modules must be installed directly in your app's package.json. React Native autolinking only links native modules that are declared by the app itself, not modules pulled in transitively by libraries. If you don't add them directly, you may see errors like "NativeModule: AsyncStorage is null" or SVGs not rendering.
If you use Expo Router or a managed workflow, no extra autolinking steps are required beyond installing the packages.
$3
This package includes full Expo autolinking support with the following configuration files:
- ✅
expo-module.config.json - Defines supported platforms and module names - ✅ react-native.config.js - Configures React Native CLI autolinking - ✅ Proper TurboModule registration for both iOS and Android
The module will be automatically detected and linked when you install it in your Expo project.
#### Expo Go vs Development Builds
Important: This package uses native modules that require custom native code. While autolinking is configured, you may encounter issues with Expo Go due to its limitations with custom native modules.
If autolinking doesn't work with Expo Go, try using development builds instead:
`bash
For iOS
npx expo run:ios
For Android
npx expo run:android `
Development builds include your custom native modules and provide the full native functionality needed for session recording.
#### Troubleshooting Expo Autolinking
If you encounter issues with module autolinking in Expo:
1. Check Expo SDK compatibility: Ensure you're using a compatible Expo SDK version 2. Clear cache: Run
npx expo start -c to clear the Expo cache 3. Use development builds: Switch from Expo Go to development builds as shown above 4. Verify configuration: Ensure the autolinking configuration files are present in your node_modules/@multiplayer-app/session-recorder-react-native/ directory
#### Expo Configuration
For Expo applications, the package automatically detects the Expo environment:
`javascript import SessionRecorder from '@multiplayer-app/session-recorder-react-native';
expo-constants - Add Expo-specific attributes to traces - Optimize performance for Expo runtime
#### Why direct install is required
- Autolinking scans only the app's
package.json - iOS CocoaPods/Android Gradle include native modules only when the app declares them - Libraries should list native requirements as peerDependencies and document installation
$3
If you encounter:
` [@RNC/AsyncStorage]: NativeModule: AsyncStorage is null `
1. Ensure
@react-native-async-storage/async-storage is installed in your app (not only in this library) 2. iOS: run cd ios && pod install, then rebuild the app 3. Clear Metro cache: npm start -- --reset-cache (or expo start -c) 4. Clean builds: uninstall the app from device/simulator and rebuild
Quick Start
$3
The
SessionRecorderProvider is required for the session recorder to work properly. It provides:
- Context for session state management - Widget modal functionality - React hooks for session control - Store management for session state
$3
#### For Basic React Native Apps (App.tsx)
`javascript import React from 'react'; import { SessionRecorderProvider, SessionRecorder, } from '@multiplayer-app/session-recorder-react-native';
NavigationContainer, set the ref in onReady:`tsx import { NavigationContainer } from '@react-navigation/native'; import { useRef } from 'react'; import { SessionRecorderProvider, SessionRecorder, } from '@multiplayer-app/session-recorder-react-native';
export default function App() { const navigationRef = useRef(null);
// Stop recording with optional reason SessionRecorder.stop('Session completed');
// Save continuous recording (for continuous mode) SessionRecorder.save();
// Set session attributes for better context SessionRecorder.setSessionAttributes({ userId: 'user123', feature: 'checkout', version: '2.1.0', });
`
Capturing exceptions
The React Native SDK automatically captures uncaught exceptions via the global error handler and converts them into error traces with standard exception attributes (
// Arbitrary messages are supported as well SessionRecorder.captureException('Payment form validation failed');
`
In Continuous mode, captured exceptions mark the current trace as ERROR and auto‑save the rolling session window so you can replay what led to the failure.
$3
This package exports a simple
ErrorBoundary component that reports render errors and shows a fallback UI.`tsx import React from 'react'; import { ErrorBoundary } from '@multiplayer-app/session-recorder-react-native';
export function AppWithBoundary() { return ( >}>
); }
`
Session Provider & Hooks
$3
To hide the floating widget button but keep the modal functionality:
useSessionRecorder hook to control the widget modal programmatically:`javascript import React from 'react'; import { View, Button } from 'react-native'; import { useSessionRecorder } from '@multiplayer-app/session-recorder-react-native';
function MyComponent() { const { openWidgetModal, closeWidgetModal } = useSessionRecorder();
return (
); }
`
$3
`javascript import React from 'react'; import { View, Button } from 'react-native'; import { useSessionRecorder } from '@multiplayer-app/session-recorder-react-native';
`javascript import React from 'react'; import { View, Text } from 'react-native'; import { useSessionRecorderStore } from '@multiplayer-app/session-recorder-react-native';
- 🎯 Gesture Recording: Track taps, swipes, and other touch interactions with target element information - 🧭 Navigation Tracking: Monitor screen transitions and navigation state changes - 📱 Screen Recording: Capture periodic screenshots (requires permissions) - 🔗 OpenTelemetry Integration: Correlate frontend actions with backend traces - 🔒 HTTP Masking: Protect sensitive data in request/response headers and bodies - ⚡ Session Management: Start, pause, resume, and stop sessions programmatically - 📦 Expo Support: Full compatibility with Expo applications including automatic environment detection - 🎨 Session Widget: Built-in UI widget for user-initiated session recording - 📊 Continuous Recording: Background recording with automatic error capture - 🌐 Network Monitoring: Track HTTP requests and responses with correlation
Gesture Recording & Target Element Information
The session recorder automatically captures target element information for all gesture interactions, enriching your OpenTelemetry traces with valuable context about what users are interacting with.
$3
When users interact with elements, the following attributes are automatically added to gesture spans:
gesture.target | Primary identifier for the target element | "Submit Button" | | gesture.target.label | Accessibility label of the element | "Submit form" | | gesture.target.role | Accessibility role of the element | "button" | | gesture.target.test_id | Test ID of the element | "submit-btn" | | gesture.target.text | Text content of the element | "Submit" |
$3
The recorder automatically extracts target information from React Native elements using the following priority:
1.
accessibilityLabel - Explicit accessibility label (highest priority) 2. Text content - Text from child elements 3. testID - Test identifier (lowest priority)
$3
To get the most useful target information in your traces, follow these practices:
#### 1. Use Accessibility Labels
`jsx accessibilityLabel="Submit user registration form" accessibilityRole="button" onPress={handleSubmit} > Submit
- Debug user interactions more effectively - Understand user behavior patterns - Identify UI issues faster - Correlate frontend actions with backend events
Screen Recording
The session recorder captures your app's UI using
react-native-view-shot, which:
- ✅ No permissions required - Captures only your app's interface - ✅ Works out of the box - No additional setup needed - ✅ Privacy-friendly - Only captures your app's content, not system UI - ❌ App-only - Cannot capture other apps or system screens
This is different from system-wide screen recording which would require permissions.
` [@RNC/AsyncStorage]: NativeModule: AsyncStorage is null `
Solution:
- Ensure
@react-native-async-storage/async-storage is installed in your app - iOS: Run cd ios && pod install - Clear Metro cache: npm start -- --reset-cache - Clean builds: Uninstall app and rebuild
#### 2. Screen Recording Not Working
- Ensure
recordScreen: true in configuration - Check that react-native-view-shot is properly installed - Verify the app has a valid view to capture - Check console logs for capture errors
#### 3. Navigation Tracking Not Working
- Make sure you've set the navigation ref:
SessionRecorder.setNavigationRef(navigationRef) - For Expo Router: Use useNavigationContainerRef() hook - For React Navigation: Set ref in onReady callback
#### 4. Gesture Recording Issues
- Gesture recording uses native modules and should work automatically - Check that
recordGestures: true is set - Ensure app is not in background mode
#### 5. Expo Environment Not Detected
- Ensure
expo-constants is installed: npx expo install expo-constants - Check that you're using the correct Expo SDK version
#### 6. TurboModule Not Found (Expo Go)
If you see this error in Expo Go:
` TurboModuleRegistry.getEnforcing(...): 'SessionRecorderNative' could not be found `
Solution: Switch to development builds instead of Expo Go:
`bash
For iOS
npx expo run:ios
For Android
npx expo run:android `
Expo Go has limitations with custom native modules. Development builds include your custom native code and will resolve this issue.
#### 7. Build Issues
- iOS: Run
cd ios && pod install after installing dependencies - Android: Run cd android && ./gradlew clean - Clear Metro cache: npm start -- --reset-cache
$3
Enable debug logging to troubleshoot issues:
`javascript import { SessionRecorder, LogLevel, } from '@multiplayer-app/session-recorder-react-native';