React Native HTTP Bridge Refurbished
The `react-native-http-bridge-refurbished` package provides a lightweight, in-app HTTP server designed for debugging React Native applications. It allows developers to expose an HTTP endpoint directly from their mobile app, facilitating interaction, data inspection, and remote control for development purposes. Currently stable at version `1.3.2`, the project sees sporadic but active maintenance, with recent updates addressing bug fixes and minor feature enhancements, such as improved URL parameter handling. As a 'refurbished' version of an earlier, potentially unmaintained library, its key differentiator is its continued support and compatibility with modern React Native versions (requiring `>=0.72`), offering a robust alternative for in-app web server functionalities.
Common errors
-
error: `react-native-http-bridge-refurbished` has not been linked. Please run `npx react-native link react-native-http-bridge-refurbished`.
cause This package includes native modules for iOS and Android, which require linking to the native projects. While React Native's autolinking usually handles this, sometimes it fails or requires a cache clear.fixRun `npx react-native link react-native-http-bridge-refurbished` to manually link the module. If the problem persists, try clearing Metro Bundler's cache (`npx react-native start --reset-cache`) and reinstalling node modules (`rm -rf node_modules && npm install` or `yarn install`). -
Network request failed
cause This error typically occurs on the client side when attempting to connect to the React Native app's HTTP server. Possible causes include incorrect IP address, an inaccessible port, or a firewall blocking the connection.fixVerify the IP address of your device (e.g., emulator/simulator IP or physical device's Wi-Fi IP). Ensure the port is not blocked by a firewall on either the device or the client machine. Confirm the `HttpBridge` server is running on the device. -
Address already in use
cause The specified port for the HTTP Bridge server is already being used by another application or process on the device.fixChoose a different port number when calling `HttpBridge.start(PORT, ...)`. Common alternatives include `8081`, `8082`, or `3000` (though `3000` might conflict with web development servers). -
java.lang.SecurityException: Permission denied (missing INTERNET permission?)
cause On Android, the application does not have the necessary `INTERNET` permission to open network sockets or accept incoming connections.fixOpen your `android/app/src/main/AndroidManifest.xml` file and add `<uses-permission android:name="android.permission.INTERNET" />` just before the `<application>` tag.
Warnings
- breaking This package has a peer dependency on `react-native >=0.72`. Projects using older versions of React Native will likely encounter build or runtime errors and should upgrade `react-native` or use an older, compatible version of this library.
- gotcha Older versions (prior to 1.2.8) experienced Android build issues, which were resolved in versions 1.2.7 and 1.2.8.
- gotcha An iOS `OS EXC_BAD_ACCESS` crash was fixed in version 1.2.4. Earlier versions might experience instability on iOS.
- gotcha When accessing the in-app HTTP server from an external client (browser, Postman, etc.), ensure you use the device's actual IP address, not `localhost` or `127.0.0.1`. Network connectivity and firewall rules may also prevent access.
- gotcha On Android, the app's `AndroidManifest.xml` must include the `android.permission.INTERNET` permission for the HTTP server to function correctly and receive network requests.
Install
-
npm install react-native-http-bridge-refurbished -
yarn add react-native-http-bridge-refurbished -
pnpm add react-native-http-bridge-refurbished
Imports
- HttpBridge
const HttpBridge = require('react-native-http-bridge-refurbished');import { HttpBridge } from 'react-native-http-bridge-refurbished'; - HttpRequest
import type { HttpRequest } from 'react-native-http-bridge-refurbished';
Quickstart
import React, { useEffect, useState } from 'react';
import { View, Text, Button, Alert, StyleSheet } from 'react-native';
import { HttpBridge, type HttpRequest } from 'react-native-http-bridge-refurbished';
const SERVER_PORT = 8080;
const App: React.FC = () => {
const [serverStatus, setServerStatus] = useState('Stopped');
const [lastRequest, setLastRequest] = useState<HttpRequest | null>(null);
useEffect(() => {
// Start the HTTP server
HttpBridge.start(SERVER_PORT, true); // true enables console logging
setServerStatus(`Running on port ${SERVER_PORT}`);
// Register a request handler
HttpBridge.onHttpRequest((request: HttpRequest) => {
console.log('Received HTTP Request:', request);
setLastRequest(request);
if (request.url === '/') {
HttpBridge.respond(
request.requestId,
200,
'application/json',
JSON.stringify({ message: 'Hello from React Native HTTP Bridge!' })
);
} else if (request.url.startsWith('/echo')) {
const urlObj = new URL(`http://localhost${request.url}`); // Use a dummy base URL to parse parameters
const echoMessage = urlObj.searchParams.get('message') || 'No message provided';
HttpBridge.respond(
request.requestId,
200,
'text/plain',
`Echo: ${echoMessage}`
);
} else {
HttpBridge.respond(
request.requestId,
404,
'text/plain',
'Not Found: Try / or /echo?message=your_text'
);
}
});
// Cleanup on component unmount
return () => {
HttpBridge.stop();
setServerStatus('Stopped');
console.log('HTTP Bridge server stopped.');
};
}, []);
const handleStopServer = () => {
HttpBridge.stop();
setServerStatus('Stopped');
Alert.alert('Server Stopped', `HTTP server on port ${SERVER_PORT} has been stopped.`);
};
return (
<View style={styles.container}>
<Text style={styles.title}>HTTP Debug Server</Text>
<Text style={styles.statusText}>Status: {serverStatus}</Text>
<Button title="Stop Server" onPress={handleStopServer} />
{lastRequest && (
<View style={styles.requestBox}>
<Text style={styles.requestHeader}>Last Request:</Text>
<Text>Method: {lastRequest.method}</Text>
<Text>URL: {lastRequest.url}</Text>
<Text numberOfLines={1}>Headers: {JSON.stringify(lastRequest.headers)}</Text>
<Text numberOfLines={1}>Body: {lastRequest.body || '(empty)'}</Text>
</View>
)}
<Text style={styles.instructions}>
Access from browser/client (use your device's IP):
`http://[YOUR_DEVICE_IP]:${SERVER_PORT}/`
`http://[YOUR_DEVICE_IP]:${SERVER_PORT}/echo?message=Hello`
</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: '#f8f8f8',
},
title: {
fontSize: 26,
fontWeight: 'bold',
marginBottom: 15,
color: '#333',
},
statusText: {
fontSize: 18,
marginBottom: 25,
color: '#555',
},
requestBox: {
marginTop: 30,
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 8,
padding: 15,
width: '100%',
backgroundColor: '#fff',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
requestHeader: {
fontWeight: 'bold',
fontSize: 16,
marginBottom: 5,
color: '#333',
},
instructions: {
marginTop: 30,
fontSize: 14,
textAlign: 'center',
color: '#777',
lineHeight: 20,
},
});
export default App;