react-native-bug-reporter
v2.4.3
Published
Universal React Native bug reporter: auto-detect screenshots, annotate, capture crashes + diagnostics, and POST to your Bug Reporter HTTP API.
Maintainers
Readme
react-native-bug-reporter
Universal bug reporting for any React Native app. Detect screenshots, annotate them, capture crashes + diagnostics, and POST everything to your Bug Reporter HTTP API with one API key.
When a user takes a screenshot anywhere in your app, a report modal pops up with the screenshot pre-attached. The user can edit it (pen / arrow / mask), adds a title/description/severity; the SDK auto-collects user, device, app, current screen, network, timestamp and uploads everything to your API.
- 📸 Automatic screenshot detection (native iOS + Android)
- ✏️ Screenshot editor — pen, arrow, 🔒 mask (redact sensitive areas)
- 💥 Auto JS crash capture — uncaught errors file a report (with crash location + breadcrumbs)
- 🪵 Diagnostics — recent console logs + network requests + breadcrumbs attached to every report
- 🏷 Category + tags on reports
- 🧩 One-component install —
<BugReporterProvider> - 🔍 Auto-collected context (device, app, user, screen, network, time)
- 🌐 Any HTTP backend — single multipart
POST /api/v1/bugswithX-Api-Key - 🎨 Themeable, TypeScript-first, autolinked
1. Install
npm install react-native-bug-reporter \
@react-native-community/netinfo react-native-device-info \
react-native-svg react-native-view-shot
cd ios && pod install && cd ..These are native modules — rebuild the app after installing. The networking
to your API is plain fetch (no extra config).
2. Wrap your app
import { BugReporterProvider } from 'react-native-bug-reporter';
export default function App() {
return (
<BugReporterProvider
config={{
baseUrl: 'https://bugsreporter.example.com',
apiKey: 'brk_xxxxxxxxxxxxxxxx',
appKey: 'my-app', // multi-app id
environment: __DEV__ ? 'development' : 'production',
getUser: () => ({ id: user.id, name: user.name, email: user.email }),
}}
>
<RootNavigator />
</BugReporterProvider>
);
}Now take a screenshot in the running app — the report modal appears with the screenshot attached. 🎉
4. Full functionality
Trigger the modal manually
import { useBugReporter } from 'react-native-bug-reporter';
function HelpScreen() {
const { openReporter } = useBugReporter();
return <Button title="Report a bug" onPress={() => openReporter()} />;
}useBugReporter() returns:
| Field | Type | Description |
| --------------------- | ----------------------- | ------------------------------------------------ |
| openReporter | (screenshot?) => void | Open the modal (optionally pre-attach an image). |
| closeReporter | () => void | Close it. |
| isOpen | boolean | Modal visibility. |
| isAutoDetectEnabled | boolean | Whether screenshot detection is on. |
Track the current screen
The SDK is navigation-agnostic. Report the active route so it's attached to bug reports. With React Navigation:
import {
setCurrentScreen,
getActiveRouteName,
} from 'react-native-bug-reporter';
<NavigationContainer
onStateChange={state => {
const route = getActiveRouteName(state);
if (route) setCurrentScreen(route);
}}
/>;…then pass getCurrentScreen in the config:
import { getCurrentScreen } from 'react-native-bug-reporter';
// config: { ..., getCurrentScreen }Or just call setCurrentScreen('Checkout') from any screen's effect.
Multi-app support
Give each app its own appKey (and appName) — every report is tagged with it,
so your backend/admin can show per-app sections and route emails per app:
<BugReporterProvider config={{ baseUrl, apiKey, appKey: 'shop', appName: 'Shop App' }}>Reports are viewed/managed in your hosted admin panel (the backend), not in the app.
API contract
The SDK sends one multipart/form-data request:
POST {baseUrl}/api/v1/bugs
X-Api-Key: <apiKey>
payload = JSON { appKey, title, description, severity, status, createdAt,
category, tags, environment, context }
screenshots[] = image file(s)context includes user, device, app, network, currentScreen, timestamp and a
diagnostics object (recent logs, network, errors with crash location, and
breadcrumbs). The server stores the report + screenshots and handles email
notifications.
Theming
config={{
baseUrl, apiKey,
theme: {
primaryColor: '#7c3aed',
backgroundColor: '#ffffff',
textColor: '#111827',
mutedColor: '#6b7280',
borderColor: '#e5e7eb',
errorColor: '#ef4444',
},
}}Callbacks & options
config={{
baseUrl, apiKey,
enabled: true, // set false to fully disable the SDK
disableAutoDetect: false, // set true for manual-only reporting
debug: __DEV__, // verbose logging
onSubmitted: (report) => analytics.track('bug_reported', { id: report.id }),
onError: (err) => console.warn(err),
}}Config reference (BugReporterConfig)
| Option | Type | Default | Description |
| -------------------- | ------------------------------ | ------------- | -------------------------------------------------------------------------------------------------------------- |
| baseUrl | string (required) | — | Bug Reporter API base URL. |
| apiKey | string (required) | — | Sent as the X-Api-Key header. |
| enabled | boolean | true | Master on/off switch. false fully disables the SDK — no detection, no crash/diagnostics hooks, openReporter is a no-op. |
| appKey | string | default | Multi-app id — tags every report so your backend can group per app. |
| appName | string | appKey | Human-friendly app name. |
| environment | string | — | Build channel sent with every report (e.g. "production"). |
| captureCrashes | boolean | true | Auto-capture uncaught JS errors as crash reports. |
| captureConsoleLogs | boolean | true | Attach recent console logs. |
| captureNetwork | boolean | true | Attach recent network requests. |
| categories | string[] | preset list | Category options in the modal. |
| getUser | () => UserInfo \| Promise<…> | — | Current signed-in user. |
| getCurrentScreen | () => string \| null | — | Active route name. |
| showContextSummary | boolean | true | Show the "Automatically attached" block (data is always collected). |
| disableAutoDetect | boolean | false | Manual-only reporting. |
| theme | BugReporterTheme | light theme | Color overrides. |
| onSubmitted | (report) => void | — | Success callback. |
| onError | (error) => void | — | Failure callback. |
| debug | boolean | false | Verbose logging. |
How screenshot capture works
Instead of reading the device Photos library (permission-heavy, may miss the frame), the native modules snapshot the current app window the instant a screenshot is detected:
- iOS —
userDidTakeScreenshotNotification→ render the key window → PNG. - Android 14+ —
Activity.registerScreenCaptureCallback→PixelCopy→ PNG. - Android ≤13 —
MediaStoreContentObserver→PixelCopy→ PNG.
The JS layer shows the image in the modal and streams it to your backend as
multipart/form-data.
The build emits CommonJS, ESM, and TypeScript declarations to lib/.
License
MIT
