@not-true/devtools
v2.1.4
Published
Remote debugging and development tools client library for React Native applications
Downloads
35
Maintainers
Readme
@not-true/devtools
Remote debugging and development tools client library for React Native applications.
Features
- 🔧 Real-time Console Logging - Automatically capture and stream console output
- 🎮 Remote REPL - Execute JavaScript commands remotely on your device
- 📱 Screenshot Capture - Take screenshots of your app remotely
- 🔄 State Synchronization - Monitor Redux, Context, and AsyncStorage state
- ⚙️ Remote Configuration - Update feature flags and config dynamically
- 🔌 Automatic Reconnection - Robust connection handling with queue management
- 📊 Device Information - Collect and display device/app metadata
- 🚀 TypeScript Support - Fully typed for better developer experience
Installation
npm install @not-true/devtools
# or
yarn add @not-true/devtoolsDependencies
The package includes socket.io-client 2.5.0 which is optimized for React Native compatibility:
npm install @not-true/devtools
# socket.io-client 2.5.0 is included as a dependencyQuick Start
Basic Setup
import RemoteDevTools from '@not-true/devtools';
const devTools = new RemoteDevTools({
serverUrl: 'http://your-devtools-server:3000',
name: 'My React Native App',
version: '1.0.0',
}, {
onConnect: () => console.log('Connected to DevTools'),
onDisconnect: () => console.log('Disconnected from DevTools'),
});
// Connect to the server
await devTools.connect();With React Hooks
import React, { useEffect } from 'react';
import { useRemoteDevTools, useReduxSync } from '@not-true/devtools';
import { store } from './store'; // Your Redux store
function App() {
const { devTools, isConnected, connect, connectionStatus } = useRemoteDevTools({
serverUrl: 'http://localhost:3000',
name: 'My App',
version: '1.0.0',
}, {
onConnect: () => console.log('DevTools connected!'),
onRemoteConfig: (config) => {
// Handle remote configuration updates
console.log('Received config:', config);
},
});
// Automatically sync Redux state
useReduxSync(devTools, store);
useEffect(() => {
connect();
}, [connect]);
return (
<div>
<p>DevTools Status: {connectionStatus}</p>
{/* Your app content */}
</div>
);
}Configuration
RemoteDevToolsConfig
interface RemoteDevToolsConfig {
serverUrl: string; // Required: WebSocket server URL
name: string; // Required: Client display name
version: string; // Required: Application version
// Optional settings
maxQueueSize?: number; // Default: 1000
maxReconnectAttempts?: number; // Default: 5
reconnectDelay?: number; // Default: 1000ms
// Feature toggles
enableConsoleLogging?: boolean; // Default: true
enableStateSync?: boolean; // Default: true
enableScreenshots?: boolean; // Default: true
enableREPL?: boolean; // Default: true
enableRemoteConfig?: boolean; // Default: true
// Screenshot settings
screenshotQuality?: number; // 0-1, default: 0.8
screenshotFormat?: 'png' | 'jpg'; // Default: 'png'
// State sync settings
stateUpdateThrottle?: number; // ms, default: 500
// Custom info
deviceInfo?: object;
clientInfo?: object;
}Usage Examples
Manual Logging
// These will be automatically captured if enableConsoleLogging is true
console.log('Hello from device!');
console.warn('Warning message');
console.error('Error occurred');
// Or send logs manually
devTools.log('info', 'Custom log message', { data: 'example' });State Synchronization
// Redux state sync (automatic with useReduxSync hook)
import { StateUtils } from '@not-true/devtools';
const stateUpdate = StateUtils.createReduxStateUpdate(store.getState());
devTools.updateState(stateUpdate);
// Custom state sync
const customState = StateUtils.createCustomStateUpdate({
userPreferences: { theme: 'dark', language: 'en' },
featureFlags: { newUI: true }
}, 'app-state');
devTools.updateState(customState);
// AsyncStorage sync
const asyncStorageUpdate = StateUtils.createAsyncStorageUpdate('userToken', 'abc123');
devTools.updateState(asyncStorageUpdate);Screenshot Capture
The client library requires you to implement your own screenshot capture (e.g., using react-native-view-shot or similar):
import { ScreenshotUtils } from '@not-true/devtools';
// You need to install and import your screenshot library
// import { captureScreen } from 'react-native-view-shot';
// Handle remote screenshot requests
const devTools = new RemoteDevTools(config, {
onScreenshotRequest: async (options) => {
// Implement your own screenshot capture
const uri = await captureScreen({
format: options.format || 'png',
quality: options.quality || 0.8,
result: 'data-uri' // or 'base64'
});
// Convert to base64 if needed
const base64 = ScreenshotUtils.dataURIToBase64(uri);
// Create screenshot data with metadata
return ScreenshotUtils.createScreenshotWithMetadata(base64, {
width: 375, // actual screen width
height: 812, // actual screen height
format: options.format || 'png'
});
}
});
// Send screenshot manually
const sendScreenshot = async () => {
try {
const uri = await captureScreen({ format: 'png', quality: 0.8 });
const base64 = ScreenshotUtils.dataURIToBase64(uri);
const screenshot = ScreenshotUtils.createScreenshotWithMetadata(base64, {
width: 375,
height: 812,
format: 'png'
});
devTools.sendScreenshot(screenshot);
} catch (error) {
console.error('Screenshot failed:', error);
}
};REPL Command Handling
const devTools = new RemoteDevTools(config, {
onREPLCommand: async (command) => {
// Handle remote JavaScript execution
try {
// Safely evaluate the command
if (command.command === 'getAppVersion()') {
return '1.0.0';
}
if (command.command === 'getCurrentUser()') {
return { id: 1, name: 'John Doe' };
}
// For security, limit what can be executed
throw new Error('Command not allowed');
} catch (error) {
throw error;
}
}
});Remote Configuration
const devTools = new RemoteDevTools(config, {
onRemoteConfig: (config) => {
// Apply configuration changes
if (config.config.enableDarkMode) {
// Enable dark mode
}
if (config.config.apiEndpoint) {
// Update API endpoint
}
// Update feature flags
updateFeatureFlags(config.config.featureFlags || {});
}
});Context State Sync
import React, { useContext } from 'react';
import { useContextSync } from '@not-true/devtools';
const ThemeContext = React.createContext({ theme: 'light' });
function MyComponent({ devTools }) {
const themeValue = useContext(ThemeContext);
// Automatically sync context value
useContextSync(devTools, themeValue, 'ThemeContext');
return <div>Component content</div>;
}Advanced Usage
Custom Queue Management
import { QueueManager } from '@not-true/devtools';
const customQueue = new QueueManager(500); // Custom size limit
// Manually manage queue
customQueue.enqueue({
type: 'log',
data: { level: 'info', message: 'Custom message' },
timestamp: Date.now()
});
// Get queue stats
const stats = customQueue.getStats();
console.log(`Queue size: ${stats.size}/${stats.maxSize}`);Device Information
import { DeviceInfoUtils } from '@not-true/devtools';
const deviceInfo = DeviceInfoUtils.getDeviceInfo();
console.log('Platform:', deviceInfo.platform);
console.log('OS Version:', deviceInfo.osVersion);
console.log('Screen Size:', deviceInfo.screenSize);
const memoryInfo = DeviceInfoUtils.getMemoryInfo();
const networkInfo = DeviceInfoUtils.getNetworkInfo();Error Handling
const devTools = new RemoteDevTools(config, {
onError: (error) => {
console.error('DevTools error:', error);
// Handle or report error
},
onReconnectError: (error) => {
console.error('Failed to reconnect:', error);
// Show user notification or fallback
}
});API Reference
RemoteDevTools Class
Methods
connect(): Promise - Connect to the serverdisconnect(): void - Disconnect from the serverlog(level, ...args): void - Send log entryupdateState(stateUpdate): void - Send state updatesendScreenshot(data): void - Send screenshot datasendREPLResult(result): void - Send REPL execution resultisConnectedToServer(): boolean - Check connection statusgetConfig(): RemoteDevToolsConfig - Get current configurationupdateConfig(config): void - Update configurationdestroy(): void - Cleanup and disconnect
React Hooks
useRemoteDevTools(config, handlers)- Main hook for RemoteDevTools integrationuseReduxSync(devTools, store, throttleMs?)- Automatic Redux state synchronizationuseREPLHandler(devTools, evaluator?)- REPL command handlinguseScreenshotHandler(devTools, capturer?)- Screenshot request handlinguseContextSync(devTools, contextValue, name, throttleMs?)- React Context synchronization
Utility Classes
DeviceInfoUtils- Device and platform informationQueueManager- Message queue managementScreenshotUtils- Screenshot capture utilitiesStateUtils- State management helpers
Development Server
This client library works with the Remote DevTools Platform server. To set up the server:
# Clone the server repository
git clone https://github.com/your-org/remote-devtools-platform
cd remote-devtools-platform
# Install dependencies
npm install
# Start development server
npm run dev
# Or start production server
npm run build && npm startThe dashboard will be available at http://localhost:3000.
Security Considerations
- REPL Execution: The remote REPL feature allows arbitrary code execution. Only use in development environments.
- Network Security: Use HTTPS/WSS in production environments.
- Data Sanitization: State data is automatically sanitized to prevent large payloads and circular references.
- Access Control: Implement proper authentication/authorization in your server setup.
Platform Support
- ✅ React Native (iOS/Android)
- ✅ Expo (managed/bare workflow)
- ⚠️ Web (limited screenshot support)
- ❌ React Native Windows/macOS (not tested)
Troubleshooting
Connection Issues
// Check if server is accessible
const devTools = new RemoteDevTools(config, {
onConnect: () => console.log('✅ Connected'),
onDisconnect: () => console.log('❌ Disconnected'),
onReconnect: (attempt) => console.log(`🔄 Reconnecting... (${attempt})`),
onError: (error) => console.error('❗ Error:', error)
});Performance Issues
// Increase throttling for state updates
const config = {
// ... other config
stateUpdateThrottle: 1000, // Update at most once per second
};
// Reduce queue size
const config = {
// ... other config
maxQueueSize: 100,
};Contributing
Contributions are welcome! Please see our contributing guidelines for more details.
License
MIT License - see LICENSE file for details.
