Crash Detection
SwiftPatch monitors app launches after every OTA update. If the new bundle crashes repeatedly before stabilizing, the SDK automatically rolls back to the last stable bundle.
If you use withSwiftPatch or SwiftPatchProvider, crash detection is already active. Nothing to enable.
How the 10-Second Window Works
After an update installs, every launch enters a crash detection window (10 seconds by default). The SDK watches for one signal: did the app render?
Step 1: Update lands in NEW_SLOT -- staged but not yet trusted.
Step 2: App launches with new bundle -- native module starts a countdown timer.
Step 3: Provider renders -- SwiftPatchProvider calls markMounted() to signal a healthy launch.
Step 4: Timer stops -- after several healthy launches, the bundle promotes to STABLE_SLOT.
If the app crashes before markMounted(), the native module increments a crash counter. After reaching the threshold (default: 2), SwiftPatch rolls back on the next launch.
Launch 1 with new bundle
[--- 10-second window ---]
App crashes at 3s -> crashCount = 1
Launch 2 with new bundle
[--- 10-second window ---]
App crashes at 1s -> crashCount = 2 (threshold reached)
Launch 3 -> Rollback to STABLE_SLOT
Integration
Automatic (Recommended)
withSwiftPatch calls markMounted() automatically when it renders:
import { withSwiftPatch } from '@swiftpatch/react-native';
function App() {
return <YourApp />;
}
export default withSwiftPatch(App);
Custom Mount Timing
If your app has heavy initialization that should succeed before the app is considered healthy:
import { useSwiftPatch } from '@swiftpatch/react-native';
function App() {
const { markMounted } = useSwiftPatch();
useEffect(() => {
async function init() {
await loadCriticalData();
await setupServices();
markMounted();
}
init();
}, []);
return <YourApp />;
}
Delaying markMounted() gives better crash coverage but increases the chance of incorrectly treating a slow startup as a crash. Balance coverage with startup time.
Configuration
export default withSwiftPatch(App, {
crashDetectionWindowMs: 15000, // 15s window (default: 10000)
maxCrashesBeforeRollback: 3, // 3 crashes before rollback (default: 2)
});
| Option | Default | Description |
|---|---|---|
crashDetectionWindowMs | 10000 | Time window after launch for crash detection |
maxCrashesBeforeRollback | 2 | Consecutive crashes before rollback |
Apps with heavy initialization (Firebase, Sentry, large data loading) may need a longer window. If your app takes more than 10 seconds to fully render, increase crashDetectionWindowMs.
Setting maxCrashesBeforeRollback to 1 means a single crash triggers rollback. This may cause false positives from transient issues. Use 2 or 3 for most apps. Reserve 1 for safety-critical applications.
Dashboard Metrics
Crash Groups
Filter by project, status, and severity. SwiftPatch groups related crashes and provides AI-powered analysis.

Per-Project Crashlytics
View crash data from Firebase at the project level. Connect Firebase in Settings > Integrations.

Key metrics:
- Crash-free rate per release -- Compare stability across versions
- Rollback count -- Devices rolled back, by release and channel
- Crash-to-rollback time -- How quickly SwiftPatch protected users
- Affected devices -- Total devices that crashed before rollback
Error Tracking Integration
Forward rollback events to your error tracking service:
import { onRollback } from '@swiftpatch/react-native';
import * as Sentry from '@sentry/react-native';
useEffect(() => {
const unsubscribe = onRollback((reason) => {
Sentry.captureMessage('SwiftPatch rollback triggered', {
extra: { reason },
});
});
return unsubscribe;
}, []);
Works with Sentry, Bugsnag, Datadog, or any custom endpoint.