react-native-api-debugger
v0.10.0
Published
API logger/visualizer for react native mobile application
Downloads
550
Readme
React Native API Debugger
A comprehensive network debugging tool for React Native applications. Monitor, inspect, and debug HTTP requests and WebSocket connections with a unified tabbed overlay interface.
Features
HTTP Debugging
- Network Interception - Automatically captures all
fetch()andXMLHttpRequestcalls - Request Details - View headers, body, response, timing, and status codes
- cURL Export - Copy requests as cURL commands
- Advanced Filtering - Filter by status code (2xx, 3xx, 4xx, 5xx), search by URL/method/body
- Export Logs - Export to HAR, Postman Collection, or JSON formats
- Request Replay - Re-execute captured requests with optional modifications
- Slow Request Detection - Visual indicator for requests exceeding threshold
- Sensitive Data Redaction - Detect and mask sensitive headers and body fields
WebSocket Debugging
- WebSocket Interception - Automatically captures all WebSocket connections
- Connection Monitoring - Track connection state (connecting, open, closing, closed)
- Message Logging - View sent and received messages with timestamps
- Message Filtering - Filter by direction (sent/received) or search by content
- Binary Support - Handles text and binary message types
- Connection Metrics - Track message counts, bytes transferred, and connection duration
- Live Indicators - Visual indicators for active connections
General
- Unified Interface - Tabbed modal with HTTP and WebSocket views
- Draggable Overlay - Floating button that can be positioned anywhere on screen
- Dark/Light Theme - Toggle between themes
- Individual Log Deletion - Remove specific entries without clearing all logs
- Device Shake Support - Shake to show/hide the debugger
- TypeScript Support - Full type definitions included
Installation
npm install react-native-api-debugger
# or
yarn add react-native-api-debugger
Optional Peer Dependencies
Install only what you need:
| Package | Required For |
|---------|--------------|
| react-native-svg (Recommended) | SVG icons (falls back to text icons) |
| react-native-gesture-handler | Draggable floating button |
| react-native-reanimated | Smooth drag animations |
| react-native-shake | Device shake detection |
| @react-native-clipboard/clipboard | Copy to clipboard |
# For draggable button
npm install react-native-gesture-handler react-native-reanimated
# For device shake
npm install react-native-shake
# For clipboard
npm install @react-native-clipboard/clipboard
# For SVG icons (optional - text fallback available)
npm install react-native-svgFor Expo SDK ≤ 53, use
react-native-reanimatedversion 3.x.x
Quick Setup
1. Basic Usage (HTTP Only)
import React, { useEffect } from 'react';
import { View } from 'react-native';
import { networkLogger, NetworkLoggerOverlay } from 'react-native-api-debugger';
export default function App() {
useEffect(() => {
networkLogger.setupInterceptor();
}, []);
return (
<View style={{ flex: 1 }}>
{/* Your app content */}
<NetworkLoggerOverlay
networkLogger={networkLogger}
draggable={false}
enableDeviceShake={false}
useCopyToClipboard={false}
/>
</View>
);
}2. Full Setup (HTTP + WebSocket)
Use NetworkLoggerOverlay with enableWebSocket={true} for the unified tabbed interface.
import React, { useEffect } from 'react';
import { View } from 'react-native';
import {
networkLogger,
webSocketLogger,
NetworkLoggerOverlay
} from 'react-native-api-debugger';
export default function App() {
useEffect(() => {
// Setup HTTP interceptor
networkLogger.setupInterceptor();
// Setup WebSocket interceptor
webSocketLogger.setupInterceptor();
}, []);
return (
<View style={{ flex: 1 }}>
{/* Your app content */}
<NetworkLoggerOverlay
networkLogger={networkLogger}
webSocketLogger={webSocketLogger}
enableWebSocket={true}
draggable={false}
/>
</View>
);
}3. With Draggable Button
Requires react-native-gesture-handler and react-native-reanimated.
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import {
networkLogger,
webSocketLogger,
NetworkLoggerOverlay
} from 'react-native-api-debugger';
export default function App() {
useEffect(() => {
networkLogger.setupInterceptor();
webSocketLogger.setupInterceptor();
}, []);
return (
<GestureHandlerRootView style={{ flex: 1 }}>
{/* Your app content */}
<NetworkLoggerOverlay
networkLogger={networkLogger}
webSocketLogger={webSocketLogger}
enableWebSocket={true}
draggable={true}
/>
</GestureHandlerRootView>
);
}4. Full Featured Setup
<NetworkLoggerOverlay
networkLogger={networkLogger}
webSocketLogger={webSocketLogger}
enableWebSocket={true}
draggable={true}
enableDeviceShake={true}
useCopyToClipboard={true}
showRequestHeader={true}
showResponseHeader={true}
theme="dark"
onThemeChange={(theme) => console.log('Theme:', theme)}
/>Advanced Usage
Configuration Options
Configure the interceptor with custom settings:
import { networkLogger } from 'react-native-api-debugger';
useEffect(() => {
networkLogger.configure({
maxLogs: 50, // Maximum logs to store (default: 100)
ignoredUrls: ['/health', '/ping'], // URL patterns to ignore
ignoredDomains: ['analytics.example.com'],
ignoredMethods: ['OPTIONS'], // HTTP methods to ignore
slowRequestThreshold: 2000, // Mark requests slower than 2s
});
networkLogger.setupInterceptor();
}, []);NetworkLogger Methods
import { networkLogger } from 'react-native-api-debugger';
// Initialize interception
networkLogger.setupInterceptor();
// Get all logs
const logs = networkLogger.getLogs();
// Get log count
const count = networkLogger.getLogCount();
// Clear all logs
networkLogger.clearLogs();
// Delete a specific log
networkLogger.deleteLog(logId);
// Enable/disable logging
networkLogger.enable();
networkLogger.disable();
// Check if enabled
const isEnabled = networkLogger.isLoggerEnabled();
// Update configuration
networkLogger.configure({ maxLogs: 200 });
// Get current configuration
const config = networkLogger.getConfig();Subscribe to Log Changes
useEffect(() => {
const unsubscribeHttp = networkLogger.subscribe((logs) => {
console.log('HTTP logs updated:', logs.length);
});
const unsubscribeWs = webSocketLogger.subscribe((logs) => {
console.log('WebSocket logs updated:', logs.length);
});
return () => {
unsubscribeHttp();
unsubscribeWs();
};
}, []);Export Utilities
import { exportToHAR, exportToPostman, exportLogs } from 'react-native-api-debugger';
const logs = networkLogger.getLogs();
// Export to HAR format (for browser DevTools)
const harContent = exportToHAR(logs);
// Export to Postman Collection
const postmanContent = exportToPostman(logs, 'My API Collection');
// Export to JSON
const jsonContent = exportLogs(logs, 'json');Request Replay
import { replayRequest, canReplayRequest, getReplayWarnings } from 'react-native-api-debugger';
const log = networkLogger.getLogs()[0];
// Check if request can be replayed
if (canReplayRequest(log)) {
// Get warnings (e.g., "This request may modify data")
const warnings = getReplayWarnings(log);
// Replay with optional modifications
const result = await replayRequest(log, {
modifyHeaders: { 'Authorization': 'Bearer new-token' },
timeout: 5000,
});
if (result.success) {
console.log('Response:', result.response);
}
}Sensitive Data Detection
import { detectSensitiveData, redactNetworkLog } from 'react-native-api-debugger';
const log = networkLogger.getLogs()[0];
// Check for sensitive data
const info = detectSensitiveData(log);
if (info.hasSensitiveHeaders) {
console.log('Contains sensitive headers');
}
// Redact sensitive data before sharing
const redactedLog = redactNetworkLog(log, { enabled: true });cURL Generation
import { generateCurl } from 'react-native-api-debugger';
const log = networkLogger.getLogs()[0];
const curlCommand = generateCurl(log);
// curl -X POST 'https://api.example.com/users' -H 'Content-Type: application/json' -d '{"name":"John"}'WebSocket Logger Methods
import { webSocketLogger } from 'react-native-api-debugger';
// Initialize interception
webSocketLogger.setupInterceptor();
// Configure options
webSocketLogger.configure({
maxConnections: 50, // Maximum connections to store
captureMessages: true, // Log individual messages
maxMessagesPerConnection: 100, // Max messages per connection
ignoredUrls: ['*/health'], // URL patterns to ignore
});
// Get all logs
const logs = webSocketLogger.getLogs();
// Get log count
const count = webSocketLogger.getLogCount();
// Clear all logs
webSocketLogger.clearLogs();
// Delete a specific log
webSocketLogger.deleteLog(logId);
// Close an active connection
webSocketLogger.closeConnection(logId);
// Enable/disable logging
webSocketLogger.enable();
webSocketLogger.disable();
// Get active connections count
const activeCount = webSocketLogger.getActiveConnectionsCount();
// Restore original WebSocket (remove interception)
webSocketLogger.restoreInterceptor();API Reference
NetworkLoggerOverlay Props
The unified overlay component with HTTP and optional WebSocket tabs.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| networkLogger | NetworkLogger | Required | HTTP logger instance |
| webSocketLogger | WebSocketLogger | - | WebSocket logger instance (required if enableWebSocket is true) |
| enabled | boolean | __DEV__ | Enable/disable the overlay |
| enableWebSocket | boolean | false | Enable WebSocket debugging tab |
| draggable | boolean | false | Enable draggable button |
| enableDeviceShake | boolean | false | Show on device shake |
| useCopyToClipboard | boolean | false | Enable clipboard copy |
| showRequestHeader | boolean | false | Show request headers |
| showResponseHeader | boolean | false | Show response headers |
| theme | 'light' \| 'dark' | 'dark' | Color theme |
| onThemeChange | (theme) => void | - | Theme change callback |
NetworkLoggerConfig
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| maxLogs | number | 100 | Maximum logs to store |
| ignoredUrls | string[] | [] | URL patterns to ignore |
| ignoredDomains | string[] | [] | Domains to ignore |
| ignoredMethods | string[] | [] | HTTP methods to ignore |
| redactHeaders | string[] | ['Authorization', ...] | Headers to redact |
| enableRedaction | boolean | false | Enable auto-redaction |
| slowRequestThreshold | number | 3000 | Slow request threshold (ms) |
NetworkLog Type
interface NetworkLog {
id: number;
method: string;
url: string;
headers: Record<string, string>;
body: string | null;
timestamp: string;
startTime: number;
response?: {
status: number;
statusText: string;
headers: Record<string, string>;
body: string;
duration: number;
};
error?: string;
duration?: number;
isSlow?: boolean;
bookmarked?: boolean;
}WebSocketLog Type
interface WebSocketLog {
id: number;
url: string;
state: 'connecting' | 'open' | 'closing' | 'closed';
protocols?: string[];
connectTime: string;
openTime?: string;
closeTime?: string;
closeCode?: number;
closeReason?: string;
error?: string;
handshakeDuration?: number;
messages: WebSocketMessage[];
messageCount: { sent: number; received: number };
bytesReceived: number;
bytesSent: number;
}
interface WebSocketMessage {
id: number;
direction: 'sent' | 'received';
data: string;
dataType: 'text' | 'binary';
timestamp: string;
size: number;
}WebSocketLoggerConfig
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| maxConnections | number | 100 | Maximum connections to store |
| captureMessages | boolean | true | Log individual messages |
| maxMessagesPerConnection | number | 100 | Max messages per connection |
| ignoredUrls | string[] | [] | URL patterns to ignore |
Production Safety
The overlay is disabled by default in production (enabled defaults to __DEV__). To explicitly control:
<NetworkLoggerOverlay
networkLogger={networkLogger}
enabled={__DEV__} // Only in development
/>For staging environments:
const showDebugger = __DEV__ || process.env.STAGING === 'true';
<NetworkLoggerOverlay
networkLogger={networkLogger}
enabled={showDebugger}
/>Troubleshooting
Draggable button not working
Ensure your app is wrapped with GestureHandlerRootView:
import { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
{/* App content */}
</GestureHandlerRootView>
);
}Share sheet not appearing
The share sheet requires the main modal to close first. This is handled automatically - ensure you're using the latest version.
Requests not being captured
Make sure setupInterceptor() is called before any network requests:
useEffect(() => {
networkLogger.setupInterceptor();
webSocketLogger.setupInterceptor();
}, []); // Empty dependency array - runs once on mountWebSocket connections not appearing
Ensure you have:
- Called
webSocketLogger.setupInterceptor()before any WebSocket connections - Set
enableWebSocket={true}on the NetworkLoggerOverlay - Passed the
webSocketLoggerprop
<NetworkLoggerOverlay
networkLogger={networkLogger}
webSocketLogger={webSocketLogger}
enableWebSocket={true} // Required to show WebSocket tab
draggable={true}
/>Setup error messages
The debugger will throw helpful error messages if interceptors aren't initialized:
- HTTP: If
networkLogger.setupInterceptor()wasn't called before rendering - WebSocket: If
enableWebSocket={true}butwebSocketLogger.setupInterceptor()wasn't called
These errors include code examples to help you fix the issue quickly.
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make changes and run tests:
yarn test - Commit:
git commit -m 'Add my feature' - Push:
git push origin feature/my-feature - Open a Pull Request
Development
git clone https://github.com/cmcWebCode40/react-native-api-debugger.git
cd react-native-api-debugger
yarn install
# Run example app
cd example
yarn install
yarn ios # or yarn androidLicense
MIT License - see LICENSE for details.
Support
- Bug Reports: GitHub Issues
- Feature Requests: GitHub Discussions
