AI-powered crash analysis is now available on all plans — including Free.Read the crash analysis guide

Expo Crash Reporting: Complete Setup Guide

NFNourin Mahfuj Finick··8 min read

Expo managed workflow apps trade flexibility for simplicity — you don't touch native code, but you also can't use arbitrary native modules. Crash reporting in a managed workflow app has a few specific constraints you need to know about before you start.

This guide covers everything: installing the SDK in a managed project, configuring EAS Build for source maps, tracking navigation with Expo Router, and verifying your setup works in production.

Managed vs Bare Workflow: What's Different

In a bare workflow app, you run npx pod-install and link native modules directly. In a managed workflow app, Expo manages native code for you — you can only use modules that Expo's managed infrastructure supports.

BugsPulse's React Native SDK works in managed workflow because it uses Expo-compatible native modules. Install with npx expo install (not npm install) to ensure the correct compatible version is resolved:

npx expo install @bugspulse/react-native

No pod-install, no android/ edits needed.

Initialization

Initialize BugsPulse in your root _layout.tsx (Expo Router) or App.tsx (Expo classic):

// app/_layout.tsx (Expo Router)
import BugsPulse from '@bugspulse/react-native';
import { useEffect } from 'react';
import { Stack } from 'expo-router';
 
BugsPulse.init({
  apiKey: process.env.EXPO_PUBLIC_BUGSPULSE_KEY!,
  environment: process.env.EXPO_PUBLIC_ENV ?? 'production',
  sessionReplay: true,
  captureNetworkRequests: true,
});
 
export default function RootLayout() {
  return <Stack />;
}

Store your API key in a .env.local file — Expo's config system picks up any EXPO_PUBLIC_ prefixed variable automatically:

# .env.local
EXPO_PUBLIC_BUGSPULSE_KEY=bp_your_project_key
EXPO_PUBLIC_ENV=production

Expo Router Navigation Tracking

Expo Router is file-based routing built on React Navigation. To track screen views as breadcrumbs:

// app/_layout.tsx
import { useNavigationContainerRef } from 'expo-router';
import BugsPulse from '@bugspulse/react-native';
import { useEffect, useRef } from 'react';
import { Stack } from 'expo-router';
 
export default function RootLayout() {
  const routeNameRef = useRef<string | undefined>();
 
  return (
    <Stack
      screenOptions={{ headerShown: false }}
      // Track navigation on each route change
    >
      {/* Use Expo Router's built-in navigation events */}
    </Stack>
  );
}

For Expo Router v3+, use the useSegments hook to capture the current route:

import { useSegments, usePathname } from 'expo-router';
import { useEffect } from 'react';
import BugsPulse from '@bugspulse/react-native';
 
function NavigationTracker() {
  const pathname = usePathname();
 
  useEffect(() => {
    BugsPulse.setCurrentScreen(pathname);
    BugsPulse.addBreadcrumb({
      message: `Navigated to ${pathname}`,
      category: 'navigation',
    });
  }, [pathname]);
 
  return null;
}
 
// Add <NavigationTracker /> inside your RootLayout

EAS Build + Source Maps

Without source maps, production crash stack traces are unreadable. EAS Build can generate them automatically.

eas.json configuration

{
 
## Related reading
 
- [React Native Crash Reporting: The Complete Setup Guide (2026)](/blog/react-native-crash-reporting-setup-guide)
- [React Native Error Tracking in Production: A Complete Guide](/blog/react-native-error-tracking)
- [The Complete Guide to React Native Crash Debugging](/blog/react-native-crash-debugging-guide)
 
**Try BugsPulse free** event-based session replay, AI-powered crash analysis, and native crash capture for React Native and Flutter. 500 sessions/month, no credit card required. [Get started at bugspulse.com](https://bugspulse.com)