
sentry-react-native-sdk
Full Sentry SDK setup for React Native and Expo. Use when asked to "add Sentry to React Native", "install @sentry/react-native", "setup Sentry in Expo", or configure error monitoring, tracing, profiling, session replay, or logging for React Native applications. Supports Expo managed, Expo bare, and vanilla React Native.
- Installs
- 540
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/getsentry/sentry-agent-skills --skill sentry-react-native-sdk- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads sentry-react-native-sdk automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Sentry React Native SDK
Opinionated wizard that scans your React Native or Expo project and guides you through complete Sentry setup — error monitoring, tracing, profiling, session replay, logging, and more.
Invoke This Skill When
- User asks to "add Sentry to React Native" or "set up Sentry" in an RN or Expo app
- User wants error monitoring, tracing, profiling, session replay, or logging in React Native
- User mentions
@sentry/react-native, mobile error tracking, or Sentry for Expo - User wants to monitor native crashes, ANRs, or app hangs on iOS/Android
Note: SDK versions and APIs below reflect current Sentry docs at time of writing (
@sentry/react-native≥6.0.0, minimum recommended ≥8.0.0). Always verify against docs.sentry.io/platforms/react-native/ before implementing.
Phase 1: Detect
Run these commands to understand the project before making any recommendations:
# Detect project type and existing Sentry
cat package.json | grep -E '"(react-native|expo|@expo|@sentry/react-native|sentry-expo)"'
# Distinguish Expo managed vs bare vs vanilla RN
ls app.json app.config.js app.config.ts 2>/dev/null
cat app.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print('Expo managed' if 'expo' in d else 'Bare/Vanilla')" 2>/dev/null
# Check Expo SDK version (important: Expo SDK 50+ required for @sentry/react-native)
cat package.json | grep '"expo"'
# Detect navigation library
grep -E '"(@react-navigation/native|react-native-navigation)"' package.json
# Detect state management (Redux → breadcrumb integration available)
grep -E '"(redux|@reduxjs/toolkit|zustand|mobx)"' package.json
# Check for existing Sentry initialization
grep -r "Sentry.init" src/ app/ App.tsx App.js _layout.tsx 2>/dev/null | head -5
# Detect Hermes (affects source map handling)
cat android/app/build.gradle 2>/dev/null | grep -i hermes
cat ios/Podfile 2>/dev/null | grep -i hermes
# Detect Expo Router
ls app/_layout.tsx app/_layout.js 2>/dev/null
# Detect backend for cross-link
ls backend/ server/ api/ 2>/dev/null
find . -maxdepth 3 \( -name "go.mod" -o -name "requirements.txt" -o -name "Gemfile" -o -name "package.json" \) 2>/dev/null | grep -v node_modules | head -10
What to determine:
| Question | Impact |
|---|---|
expo in package.json? | Expo path (config plugin + getSentryExpoConfig) vs bare/vanilla RN path |
| Expo SDK ≥50? | @sentry/react-native directly; older = sentry-expo (legacy, do not use) |
app.json has "expo" key? | Managed Expo — wizard is simplest; config plugin handles all native config |
app/_layout.tsx present? | Expo Router project — init goes in _layout.tsx |
@sentry/react-native already in package.json? | Skip install, jump to feature config |
@react-navigation/native present? | Recommend reactNavigationIntegration for screen tracking |
react-native-navigation present? | Recommend reactNativeNavigationIntegration (Wix) |
| Backend directory detected? | Trigger Phase 4 cross-link |
Phase 2: Recommend
Present a concrete recommendation based on what you found. Don't ask open-ended questions — lead with a proposal:
Recommended (core coverage — always set up these):
- ✅ Error Monitoring — captures JS exceptions, native crashes (iOS + Android), ANRs, and app hangs
- ✅ Tracing — mobile performance is critical; auto-instruments navigation, app start, network requests
- ✅ Session Replay — mobile replay captures screenshots and touch events for debugging user issues
Optional (enhanced observability):
- ⚡ Profiling — CPU profiling on iOS (JS profiling cross-platform); low overhead in production
- ⚡ Logging — structured logs via
Sentry.logger.*; links to traces for full context - ⚡ User Feedback — collect user-submitted bug reports directly from your app
Recommendation logic:
| Feature | Recommend when... |
|---|---|
| Error Monitoring | Always — non-negotiable baseline for any mobile app |
| Tracing | Always for mobile — app start, navigation, and network latency matter |
| Session Replay | User-facing production app; debug user-reported issues visually |
| Profiling | Performance-sensitive screens, startup time concerns, or production perf investigations |
| Logging | App uses structured logging, or you want log-to-trace correlation in Sentry |
| User Feedback | Beta or customer-facing app where you want user-submitted bug reports |
Propose: "For your [Expo managed / bare RN] app, I recommend setting up Error Monitoring + Tracing + Session Replay. Want me to also add Profiling and Logging?"
Phase 3: Guide
Determine Your Setup Path
| Project type | Recommended setup | Complexity |
|---|---|---|
| Expo managed (SDK 50+) | Wizard CLI or manual with config plugin | Low — wizard does everything |
| Expo bare (SDK 50+) | Wizard CLI recommended | Medium — handles iOS/Android config |
| Vanilla React Native (0.69+) | Wizard CLI recommended | Medium — handles Xcode + Gradle |
| Expo SDK <50 | Use sentry-expo (legacy) | See legacy docs |
Path A: Wizard CLI (Recommended for all project types)
Run the wizard — it walks you through login, org/project selection, and auth token setup interactively. It then handles installation, native config, source map upload, and initial Sentry.init():
npx @sentry/wizard@latest -i reactNative
What the wizard creates/modifies:
| File | Action | Purpose |
|---|---|---|
package.json | Installs @sentry/react-native | Core SDK |
metro.config.js | Adds @sentry/react-native/metro serializer | Source map generation |
app.json | Adds @sentry/react-native/expo plugin (Expo only) | Config plugin for native builds |
App.tsx / _layout.tsx | Adds Sentry.init() and Sentry.wrap() | SDK initialization |
ios/sentry.properties | Stores org/project/token | iOS source map + dSYM upload |
android/sentry.properties | Stores org/project/token | Android source map upload |
android/app/build.gradle | Adds Sentry Gradle plugin | Android source maps + proguard |
ios/[AppName].xcodeproj | Wraps "Bundle RN" build phase + adds dSYM upload | iOS symbol upload |
.env.local | SENTRY_AUTH_TOKEN | Auth token (add to .gitignore) |
After the wizard runs, skip to Verification.
Path B: Manual — Expo Managed (SDK 50+)
Step 1 — Install
npx expo install @sentry/react-native
Step 2 — metro.config.js
const { getSentryExpoConfig } = require("@sentry/react-native/metro");
const config = getSentryExpoConfig(__dirname);
module.exports = config;
If metro.config.js doesn't exist yet:
npx expo customize metro.config.js
# Then replace contents with the above
Step 3 — app.json — Add Expo config plugin
{
"expo": {
"plugins": [
[
"@sentry/react-native/expo",
{
"url": "https://sentry.io/",
"project": "YOUR_PROJECT_SLUG",
"organization": "YOUR_ORG_SLUG"
}
]
]
}
}
Note: Set
SENTRY_AUTH_TOKENas an environment variable for native builds — never commit it to version control.
Step 4 — Initialize Sentry
For Expo Router (app/_layout.tsx):
import { Stack, useNavigationContainerRef } from "expo-router";
import { isRunningInExpoGo } from "expo";
import * as Sentry from "@sentry/react-native";
import React from "react";
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: !isRunningInExpoGo(), // disabled in Expo Go
});
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN ?? "YOUR_SENTRY_DSN",
sendDefaultPii: true,
// Tracing
tracesSampleRate: 1.0, // lower to 0.1–0.2 in production
// Profiling
profilesSampleRate: 1.0,
// Session Replay
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
// Logging (SDK ≥7.0.0)
enableLogs: true,
// Navigation
integrations: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: !isRunningInExpoGo(), // slow/frozen frames
environment: __DEV__ ? "development" : "production",
});
function RootLayout() {
const ref = useNavigationContainerRef();
React.useEffect(() => {
if (ref) {
navigationIntegration.registerNavigationContainer(ref);
}
}, [ref]);
return <Stack />;
}
export default Sentry.wrap(RootLayout);
For standard Expo (App.tsx):
import { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
import { isRunningInExpoGo } from "expo";
import * as Sentry from "@sentry/react-native";
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: !isRunningInExpoGo(),
});
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN ?? "YOUR_SENTRY_DSN",
sendDefaultPii: true,
tracesSampleRate: 1.0,
profilesSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
enableLogs: true,
integrations: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: !isRunningInExpoGo(),
environment: __DEV__ ? "development" : "production",
});
const navigationRef = createNavigationContainerRef();
function App() {
return (
<NavigationContainer
ref={navigationRef}
onReady={() => {
navigationIntegration.registerNavigationContainer(navigationRef);
}}
>
{/* your navigation here */}
</NavigationContainer>
);
}
export default Sentry.wrap(App);
Path C: Manual — Bare React Native (0.69+)
Step 1 — Install
npm install @sentry/react-native --save
cd ios && pod install
Step 2 — metro.config.js
const { getDefaultConfig } = require("@react-native/metro-config");
const { withSentryConfig } = require("@sentry/react-native/metro");
const config = getDefaultConfig(__dirname);
module.exports = withSentryConfig(config);
Step 3 — iOS: Modify Xcode build phase
Open ios/[AppName].xcodeproj in Xcode. Find the "Bundle React Native code and images" build phase and replace the script content with:
# RN 0.81.1+
set -e
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
SENTRY_XCODE="../node_modules/@sentry/react-native/scripts/sentry-xcode.sh"
/bin/sh -c "$WITH_ENVIRONMENT $SENTRY_XCODE"
Step 4 — iOS: Add "Upload Debug Symbols to Sentry" build phase
Add a new Run Script build phase in Xcode (after the bundle phase):
/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh
Step 5 — iOS: ios/sentry.properties
defaults.url=https://sentry.io/
defaults.org=YOUR_ORG_SLUG
defaults.project=YOUR_PROJECT_SLUG
auth.token=YOUR_ORG_AUTH_TOKEN
Step 6 — Android: android/app/build.gradle
Add before the android {} block:
apply from: "../../node_modules/@sentry/react-native/sentry.gradle"
Step 7 — Android: android/sentry.properties
defaults.url=https://sentry.io/
defaults.org=YOUR_ORG_SLUG
defaults.project=YOUR_PROJECT_SLUG
auth.token=YOUR_ORG_AUTH_TOKEN
Step 8 — Initialize Sentry (App.tsx or entry point)
import { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
import * as Sentry from "@sentry/react-native";
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: true,
});
Sentry.init({
dsn: "YOUR_SENTRY_DSN",
sendDefaultPii: true,
tracesSampleRate: 1.0,
profilesSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
enableLogs: true,
integrations: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: true,
environment: __DEV__ ? "development" : "production",
});
const navigationRef = createNavigationContainerRef();
function App() {
return (
<NavigationContainer
ref={navigationRef}
onReady={() => {
navigationIntegration.registerNavigationContainer(navigationRef);
}}
>
{/* your navigation here */}
</NavigationContainer>
);
}
export default Sentry.wrap(App);
Quick Reference: Full-Featured Sentry.init()
This is the recommended starting configuration with all features enabled:
import * as Sentry from "@sentry/react-native";
Sentry.init({
dsn: "YOUR_SENTRY_DSN",
sendDefaultPii: true,
// Tracing — lower to 0.1–0.2 in high-traffic production
tracesSampleRate: 1.0,
// Profiling — runs on a subset of traced transactions
profilesSampleRate: 1.0,
// Session Replay — always capture on error, sample 10% of all sessions
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
// Logging — enable Sentry.logger.* API
enableLogs: true,
// Integrations — mobile replay is opt-in
integrations: [
Sentry.mobileReplayIntegration({
maskAllText: true, // masks text by default for privacy
maskAllImages: true,
}),
],
// Native frames tracking (disable in Expo Go)
enableNativeFramesTracking: true,
// Environment
environment: __DEV__ ? "development" : "production",
// Release — set from CI or build system
// release: "my-app@1.0.0+1",
// dist: "1",
});
// REQUIRED: Wrap root component to capture React render errors
export default Sentry.wrap(App);
Navigation Setup — React Navigation (v5+)
import { reactNavigationIntegration } from "@sentry/react-native";
import { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
const navigationIntegration = reactNavigationIntegration({
enableTimeToInitialDisplay: true, // track TTID per screen
routeChangeTimeoutMs: 1_000, // max wait for route change to settle
ignoreEmptyBackNavigationTransactions: true,
});
// Add to Sentry.init integrations array
Sentry.init({
integrations: [navigationIntegration],
// ...
});
// In your component:
const navigationRef = createNavigationContainerRef();
<NavigationContainer
ref={navigationRef}
onReady={() => {
navigationIntegration.registerNavigationContainer(navigationRef);
}}
>
Navigation Setup — Wix React Native Navigation
import * as Sentry from "@sentry/react-native";
import { Navigation } from "react-native-navigation";
Sentry.init({
integrations: [Sentry.reactNativeNavigationIntegration({ navigation: Navigation })],
// ...
});
Wrap Your Root Component
Always wrap your root component — this enables React error boundaries and ensures crashes at the component tree level are captured:
export default Sentry.wrap(App);
For Each Agreed Feature
Walk through features one at a time. Load the reference file for each, follow its steps, then verify before moving on:
| Feature | Reference | Load when... |
|---|---|---|
| Error Monitoring | ${SKILL_ROOT}/references/error-monitoring.md | Always (baseline) |
| Tracing & Performance | ${SKILL_ROOT}/references/tracing.md | Always for mobile (app start, navigation, network) |
| Profiling | ${SKILL_ROOT}/references/profiling.md | Performance-sensitive production apps |
| Session Replay | ${SKILL_ROOT}/references/session-replay.md | User-facing apps |
| Logging | ${SKILL_ROOT}/references/logging.md | Structured logging / log-to-trace correlation |
| User Feedback | ${SKILL_ROOT}/references/user-feedback.md | Collecting user-submitted reports |
For each feature: Read ${SKILL_ROOT}/references/<feature>.md, follow steps exactly, verify it works.
Configuration Reference
Core Sentry.init() Options
| Option | Type | Default | Purpose |
|---|---|---|---|
dsn | string | — | Required. Project DSN; SDK disabled if empty. Env: SENTRY_DSN |
environment | string | — | e.g., "production", "staging". Env: SENTRY_ENVIRONMENT |
release | string | — | App version, e.g., "my-app@1.0.0+42". Env: SENTRY_RELEASE |
dist | string | — | Build number / variant identifier (max 64 chars) |
sendDefaultPii | boolean | false | Include PII: IP address, cookies, user data |
sampleRate | number | 1.0 | Error event sampling (0.0–1.0) |
maxBreadcrumbs | number | 100 | Max breadcrumbs per event |
attachStacktrace | boolean | true | Auto-attach stack traces to messages |
attachScreenshot | boolean | false | Capture screenshot on error (SDK ≥4.11.0) |
attachViewHierarchy | boolean | false | Attach JSON view hierarchy as attachment |
debug | boolean | false | Verbose SDK output. Never use in production |
enabled | boolean | true | Disable SDK entirely (e.g., for testing) |
ignoreErrors | string[] | RegExp[] | — | Drop errors matching these patterns |
ignoreTransactions | string[] | RegExp[] | — | Drop transactions matching these patterns |
maxCacheItems | number | 30 | Max offline-cached envelopes |
defaultIntegrations | boolean | true | Set false to disable all default integrations |
integrations | array | function | — | Add or filter integrations |
Tracing Options
| Option | Type | Default | Purpose |
|---|---|---|---|
tracesSampleRate | number | 0 | Transaction sample rate (0–1). Use 1.0 in dev |
tracesSampler | function | — | Per-transaction sampling; overrides tracesSampleRate |
tracePropagationTargets | (string | RegExp)[] | [/.*/] | Which API URLs receive distributed tracing headers |
profilesSampleRate | number | 0 | Profiling sample rate (applied to traced transactions) |
Native / Mobile Options
| Option | Type | Default | Purpose |
|---|---|---|---|
enableNative | boolean | true | Set false for JS-only (no native SDK) |
enableNativeCrashHandling | boolean | true | Capture native hard crashes (iOS/Android) |
enableNativeFramesTracking | boolean | — | Slow/frozen frames tracking. Disable in Expo Go |
enableWatchdogTerminationTracking | boolean | true | OOM kill detection (iOS) |
enableAppHangTracking | boolean | true | App hang detection (iOS, tvOS, macOS) |
appHangTimeoutInterval | number | 2 | Seconds before classifying as app hang (iOS) |
enableAutoPerformanceTracing | boolean | true | Auto performance instrumentation |
enableNdkScopeSync | boolean | true | Java→NDK scope sync (Android) |
attachThreads | boolean | false | Auto-attach all threads on crash (Android) |
autoInitializeNativeSdk | boolean | true | Set false for manual native init |
onReady | function | — | Callback after native SDKs initialize |
Session & Release Health Options
| Option | Type | Default | Purpose |
|---|---|---|---|
autoSessionTracking | boolean | true | Session tracking (crash-free users/sessions) |
sessionTrackingIntervalMillis | number | 30000 | ms of background before session ends |
Replay Options
| Option | Type | Default | Purpose |
|---|---|---|---|
replaysSessionSampleRate | number | 0 | Fraction of all sessions recorded |
replaysOnErrorSampleRate | number | 0 | Fraction of error sessions recorded |
Logging Options (SDK ≥7.0.0)
| Option | Type | Purpose |
|---|---|---|
enableLogs | boolean | Enable Sentry.logger.* API |
beforeSendLog | function | Filter/modify logs before sending |
logsOrigin | 'native' | 'js' | 'all' | Filter log source (SDK ≥7.7.0) |
Hook Options
| Option | Type | Purpose |
|---|---|---|
beforeSend | (event, hint) => event | null | Modify/drop JS error events. ⚠️ Does NOT apply to native crashes |
beforeSendTransaction | (event) => event | null | Modify/drop transaction events |
beforeBreadcrumb | (breadcrumb, hint) => breadcrumb | null | Process breadcrumbs before storage |
Environment Variables
| Variable | Purpose | Notes |
|---|---|---|
SENTRY_DSN | Data Source Name | Falls back from dsn option |
SENTRY_AUTH_TOKEN | Upload source maps and dSYMs | Never commit — use CI secrets |
SENTRY_ORG | Organization slug | Used by wizard and build plugins |
SENTRY_PROJECT | Project slug | Used by wizard and build plugins |
SENTRY_RELEASE | Release identifier | Falls back from release option |
SENTRY_ENVIRONMENT | Environment name | Falls back from environment option |
SENTRY_DISABLE_AUTO_UPLOAD | Skip source map upload | Set true during local builds |
EXPO_PUBLIC_SENTRY_DSN | Expo public env var for DSN | Safe to embed in client bundle |
Source Maps & Debug Symbols
Source maps and debug symbols are what transform minified stack traces into readable ones. When set up correctly, Sentry shows you the exact line of your source code that threw.
How Uploads Work
| Platform | What's uploaded | When |
|---|---|---|
| iOS (JS) | Source maps (.map files) | During Xcode build |
| iOS (Native) | dSYM bundles | During Xcode archive / Xcode Cloud |
| Android (JS) | Source maps + Hermes .hbc.map | During Gradle build |
| Android (Native) | Proguard mapping + NDK .so files | During Gradle build |
Expo: Automatic Upload
The @sentry/react-native/expo config plugin automatically sets up upload hooks for native builds. Source maps are uploaded during eas build and expo run:ios/android (release).
SENTRY_AUTH_TOKEN=sntrys_... npx expo run:ios --configuration Release
Manual Upload (bare RN)
If you need to manually upload source maps:
npx sentry-cli sourcemaps upload \
--org YOUR_ORG \
--project YOUR_PROJECT \
--release "my-app@1.0.0+1" \
./dist
Default Integrations (Auto-Enabled)
These integrations are enabled automatically — no config needed:
| Integration | What it does |
|---|---|
ReactNativeErrorHandlers | Catches unhandled JS exceptions and promise rejections |
Release | Attaches release/dist to all events |
Breadcrumbs | Records console logs, HTTP requests, user gestures as breadcrumbs |
HttpClient | Adds HTTP request/response breadcrumbs |
DeviceContext | Attaches device/OS/battery info to events |
AppContext | Attaches app version, bundle ID, and memory info |
CultureContext | Attaches locale and timezone |
Screenshot | Captures screenshot on error (when attachScreenshot: true) |
ViewHierarchy | Attaches view hierarchy (when attachViewHierarchy: true) |
NativeLinkedErrors | Links JS errors to their native crash counterparts |
Opt-In Integrations
| Integration | How to enable |
|---|---|
mobileReplayIntegration() | Add to integrations array |
reactNavigationIntegration() | Add to integrations array |
reactNativeNavigationIntegration() | Add to integrations array (Wix only) |
feedbackIntegration() | Add to integrations array (user feedback widget) |
Expo Config Plugin Reference
Configure the plugin in app.json or app.config.js:
{
"expo": {
"plugins": [
[
"@sentry/react-native/expo",
{
"url": "https://sentry.io/",
"project": "my-project",
"organization": "my-org",
"note": "Set SENTRY_AUTH_TOKEN env var for native builds"
}
]
]
}
}
Or in app.config.js (allows env var interpolation):
export default {
expo: {
plugins: [
[
"@sentry/react-native/expo",
{
url: "https://sentry.io/",
project: process.env.SENTRY_PROJECT,
organization: process.env.SENTRY_ORG,
},
],
],
},
};
Production Settings
Lower sample rates and harden config before shipping to production:
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN,
environment: __DEV__ ? "development" : "production",
// Trace 10–20% of transactions in high-traffic production
tracesSampleRate: __DEV__ ? 1.0 : 0.1,
// Profile 100% of traced transactions (profiling is always a subset of tracing)
profilesSampleRate: 1.0,
// Replay all error sessions, sample 5% of normal sessions
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: __DEV__ ? 1.0 : 0.05,
// Set release and dist for accurate source map lookup
release: "my-app@" + Application.nativeApplicationVersion,
dist: String(Application.nativeBuildVersion),
// Disable debug logging in production
debug: __DEV__,
});
Verification
After setup, test that Sentry is receiving events:
// Quick test — throws and Sentry.wrap(App) catches it
<Button
title="Test Sentry Error"
onPress={() => {
throw new Error("My first Sentry error!");
}}
/>
// Or capture manually
<Button
title="Test Sentry Message"
onPress={() => {
Sentry.captureMessage("Sentry test message", "info");
}}
/>
Check the Sentry dashboard:
- Issues → your test error should appear within seconds
- Traces → look for a "main" transaction with child spans
- Replays → session recording visible after app interaction (native build only — not Expo Go)
- Logs → structured log entries if
enableLogs: true
⚠️ Expo Go limitation: Native crashes, session replay, slow/frozen frames, TTID, and TTFD only work in native builds (
eas buildorexpo run). Expo Go runs in a JS-only mode. SetenableNativeFramesTracking: !isRunningInExpoGo()to avoid warnings.
If nothing appears:
- Set
debug: true— SDK logs to Metro console - Verify DSN is correct and the Sentry project exists
- Ensure
Sentry.wrap(App)is applied to the root component - For native crashes, build a release build (crashes in debug mode may not forward)
Phase 4: Cross-Link
After completing React Native setup, check for a backend or web frontend missing Sentry coverage:
# Adjacent backend directories
ls ../backend ../server ../api 2>/dev/null
cat ../go.mod 2>/dev/null | head -3
cat ../requirements.txt ../pyproject.toml 2>/dev/null | head -3
cat ../Gemfile 2>/dev/null | head -3
ls ../backend/package.json ../server/package.json 2>/dev/null
# Web frontend in same or sibling repo
ls ../web ../frontend ../dashboard 2>/dev/null
cat ../web/package.json ../frontend/package.json 2>/dev/null | grep -E '"react"|"svelte"|"next"'
# Check for OpenTelemetry (for distributed tracing interop)
grep -r "opentelemetry" ../backend/go.mod ../server/requirements.txt 2>/dev/null
If a backend or web frontend exists without Sentry, suggest the matching skill:
| Detected | Suggest skill |
|---|---|
Go backend (go.mod) | sentry-go-sdk |
Python backend (requirements.txt, pyproject.toml) | sentry-python-sdk |
Ruby backend (Gemfile) | sentry-ruby-sdk |
| Node.js backend (Express, Fastify, etc.) | @sentry/node — see docs.sentry.io/platforms/javascript/guides/express/ |
| React / Next.js web | sentry-react-sdk |
| Svelte / SvelteKit web | sentry-svelte-sdk |
Distributed tracing setup — if the backend skill is added, configure tracePropagationTargets in React Native to propagate trace context to your API:
Sentry.init({
tracePropagationTargets: [
"localhost",
/^https:\/\/api\.yourapp\.com/,
],
// ...
});
This links mobile transactions to backend traces in the Sentry waterfall view.
Troubleshooting
| Issue | Solution |
|---|---|
| Events not appearing in Sentry | Set debug: true, check Metro/Xcode console for SDK errors; verify DSN is correct |
pod install fails | Run cd ios && pod install --repo-update; check CocoaPods version |
| iOS build fails with Sentry script | Verify the "Bundle React Native code and images" script was replaced (not appended to) |
Android build fails after adding sentry.gradle | Ensure apply from line is before the android {} block in build.gradle |
| Android Gradle 8+ compatibility issue | Use sentry-android-gradle-plugin ≥4.0.0; check sentry.gradle version in your SDK |
| Source maps not uploading | Verify sentry.properties has a valid auth.token; check build logs for sentry-cli output |
| Source maps not resolving in Sentry | Confirm release and dist in Sentry.init() match the uploaded bundle metadata |
| Hermes source maps not working | Hermes emits .hbc.map — the Gradle plugin handles this automatically; verify sentry.gradle is applied |
| Session replay not recording | Must use a native build (not Expo Go); confirm mobileReplayIntegration() is in integrations |
| Replay shows blank/black screens | Check that maskAllText/maskAllImages settings match your privacy requirements |
| Slow/frozen frames not tracked | Set enableNativeFramesTracking: true and confirm you're on a native build (not Expo Go) |
| TTID / TTFD not appearing | Requires enableTimeToInitialDisplay: true in reactNavigationIntegration() on a native build |
| App crashes on startup after adding Sentry | Likely a native initialization error — check Xcode/Logcat logs; try enableNative: false to isolate |
| Expo SDK 49 or older | Use sentry-expo (legacy package); @sentry/react-native requires Expo SDK 50+ |
isRunningInExpoGo import error | Import from expo package: import { isRunningInExpoGo } from "expo" |
| Node not found during Xcode build | Add export NODE_BINARY=$(which node) to the Xcode build phase, or symlink: ln -s $(which node) /usr/local/bin/node |
| Expo Go warning about native features | Use isRunningInExpoGo() guard: enableNativeFramesTracking: !isRunningInExpoGo() |
beforeSend not firing for native crashes | Expected — beforeSend only intercepts JS-layer errors; native crashes bypass it |
| Android 15+ (16KB page size) crash | Upgrade to @sentry/react-native ≥6.3.0 |
| Too many transactions in dashboard | Lower tracesSampleRate to 0.1 or use tracesSampler to drop health checks |
SENTRY_AUTH_TOKEN exposed in app bundle | SENTRY_AUTH_TOKEN is for build-time upload only — never pass it to Sentry.init() |
| EAS Build: Sentry auth token missing | Set SENTRY_AUTH_TOKEN as an EAS secret: eas secret:create --name SENTRY_AUTH_TOKEN |
FAQ
What does the sentry-react-native-sdk skill do?
Full Sentry SDK setup for React Native and Expo. Use when asked to "add Sentry to React Native", "install @sentry/react-native", "setup Sentry in Expo", or configure error monitoring, tracing, profiling, session replay, or logging for React Native applications. Supports Expo managed, Expo bare, and vanilla React Native.
How do I install sentry-react-native-sdk?
Run npx skills add https://github.com/getsentry/sentry-agent-skills --skill sentry-react-native-sdk in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/sentry-react-native-sdk/ (personal) or .claude/skills/sentry-react-native-sdk/ (project).
Which AI agents can use sentry-react-native-sdk?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is sentry-react-native-sdk safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains sentry-react-native-sdk?
It is published by getsentry in getsentry/sentry-agent-skills, and it is an official skill from the maker of the technology it covers. It has 540 recorded installs.
More from getsentry/sentry-agent-skills
sentry-fix-issues
getsentry/sentry-agent-skills
Find and fix issues from Sentry using MCP. Use when asked to fix Sentry errors, debug production issues, investigate exceptions, or resolve bugs reported in Sentry. Methodically analyzes stack traces, breadcrumbs, traces, and context to identify root causes.
sentry-react-setup
getsentry/sentry-agent-skills
Setup Sentry in React apps. Use when asked to add Sentry to React, install @sentry/react, or configure error monitoring, error boundaries, session replay, or browser tracing for React applications.
sentry-setup-ai-monitoring
getsentry/sentry-agent-skills
Setup Sentry AI Agent Monitoring in any project. Use when asked to monitor LLM calls, track AI agents, or instrument OpenAI/Anthropic/Vercel AI/LangChain/Google GenAI/Pydantic AI. Detects installed AI SDKs and configures appropriate integrations.
sentry-nextjs-sdk
getsentry/sentry-agent-skills
Full Sentry SDK setup for Next.js. Use when asked to "add Sentry to Next.js", "install @sentry/nextjs", or configure error monitoring, tracing, session replay, logging, profiling, AI monitoring, or crons for Next.js applications. Supports Next.js 13+ with App Router and Pages Router.
sentry-pr-code-review
getsentry/sentry-agent-skills
Review a project's PRs to check for issues detected in code review by Seer Bug Prediction. Use when asked to review or fix issues identified by Sentry in PR comments, or to find recent PRs with Sentry feedback.
sentry-create-alert
getsentry/sentry-agent-skills
Create Sentry alerts using the workflow engine API. Use when asked to create alerts, set up notifications, configure issue priority alerts, or build workflow automations. Supports email, Slack, PagerDuty, Discord, and other notification actions.
Popular devops & cloud skills
microsoft-foundry
microsoft/azure-skills
Build, deploy, evaluate, optimize, fine-tune, and manage Microsoft Foundry agents, models, and resources end to end. USE FOR: foundry, azd ai agent, azd provision/deploy, hosted agent scaffold/develop/run/deploy/troubleshoot, prompt agent create, managed harness agent create, GitHub Copilot harness agent, create agent, update agent, add tool to agent, invoke agent, agent insights, evaluate agent, batch eval, continuous eval, continuous monitoring, agent CI/CD, optimize prompt, improve prompt, optimize agent instructions, Agent Optimizer scaffold, dataset curation from traces, deploy model, model fine-tuning (SFT/DPO/RFT), Foundry project, RBAC, role assignment, permissions, quota, capacity, region, deployment failure, AI Services, create Foundry resource, knowledge index, customize deployment, onboard, availability, training-data, grader, distillation, large file upload. DO NOT USE FOR: Azure Functions, App Service, general Azure deploy (use azure-deploy), general Azure prep (use azure
azure-diagnostics
microsoft/azure-skills
Debug Azure production issues on Azure using AppLens, Azure Monitor, resource health, and safe triage. WHEN: debug production issues, troubleshoot app service, app service high CPU, app service deployment failure, troubleshoot container apps, container app 503 or target port mismatch, troubleshoot functions, function telemetry missing or stopped after a config/connection-string change, troubleshoot AKS, VM RDP, Linux SSH, VM black screen, can't connect to VM, reset VM password, NSG or firewall blocking, kubectl cannot connect, kube-system/CoreDNS failures, pod pending, crashloop, node not ready, upgrade failures, analyze logs, KQL, insights, image pull failures, cold start issues, health probe failures, resource health, root cause of errors, troubleshoot event hubs, troubleshoot service bus, messaging SDK error, AMQP connection failure, message lock lost, lock renewal during long-running processing, service bus dead letter.
azure-prepare
microsoft/azure-skills
Prepare azd-based Azure projects for deployment: generates azure.yaml, infrastructure (Bicep/Terraform), and Dockerfiles for the Azure Developer CLI (azd) workflow. USE ONLY when the user explicitly wants to use azd as the deployment tool, or the project already has an azure.yaml file. DO NOT USE FOR: non-azd deployments, Python App Service code-only deploys (use python-appservice-deploy), or cross-cloud migration (use azure-cloud-migrate). WHEN: prepare app for azd, create azure.yaml, set up azd infrastructure, modernize app for Azure with azd, deploy with azd, function app, timer trigger, service bus trigger, event-driven function, managed identity, generate Bicep, generate Terraform, create and deploy to Azure.
azure-ai
microsoft/azure-skills
Use for Azure AI: Search, Speech, OpenAI, Document Intelligence. Helps with search, vector/hybrid search, speech-to-text, text-to-speech, transcription, OCR. WHEN: AI Search, query search, vector search, hybrid search, semantic search, speech-to-text, text-to-speech, transcribe, OCR, convert text to speech.
azure-deploy
microsoft/azure-skills
Execute Azure deployments for ALREADY-PREPARED applications that have existing .azure/deployment-plan.md and infrastructure files. DO NOT use this skill when the user asks to CREATE a new application — use azure-prepare instead. This skill runs azd up, azd deploy, terraform apply, and az deployment commands with built-in error recovery. Requires .azure/deployment-plan.md from azure-prepare and validated status from azure-validate. WHEN: "run azd up", "run azd deploy", "execute deployment", "push to production", "push to cloud", "go live", "ship it", "bicep deploy", "terraform apply", "publish to Azure", "launch on Azure". DO NOT USE WHEN: "create and deploy", "build and deploy", "create a new app", "set up infrastructure", "create and deploy to Azure using Terraform" — use azure-prepare for these.
azure-validate
microsoft/azure-skills
Pre-deployment validation for Azure readiness. Run deep checks on configuration, infrastructure (Bicep or Terraform), RBAC role assignments, managed identity permissions, and prerequisites before deploying. WHEN: validate my app, check deployment readiness, run preflight checks, verify configuration, check if ready to deploy, validate azure.yaml, validate Bicep, test before deploying, troubleshoot deployment errors, validate Azure Functions, validate function app, validate serverless deployment, verify RBAC roles, check role assignments, review managed identity permissions, what-if analysis, validate Container Apps deployment.