Automatically detect React Native platform and rewrite API URLs for local development
When developing React Native apps, you often face this frustrating issue:
// β This works in iOS Simulator but fails on Android device
const response = await fetch('http://localhost:8000/api/users');
// Error: Network request failedWhy does this happen?
- iOS Simulator can access
localhostdirectly - Android Emulator needs
10.0.2.2instead oflocalhost - Physical devices need your computer's actual IP address
- Different platforms require different URL configurations
react-native-dev-proxy automatically handles URL rewriting for you:
// β
This works everywhere - iOS, Android, simulators, and devices
import { withDevProxy } from 'react-native-dev-proxy';
import axios from 'axios';
const api = withDevProxy(axios.create({
baseURL: 'http://localhost:8000',
}), { strategy: 'auto' });
const users = await api.get('/api/users'); // Works everywhere!npm install react-native-dev-proxy
# or
yarn add react-native-dev-proxynpx rn-dev-proxy patch
Running the patch command to configure your React Native project
import { withDevProxy } from 'react-native-dev-proxy';
import axios from 'axios';
const api = withDevProxy(
axios.create({
baseURL: 'http://localhost:8000',
timeout: 10000,
}),
{
strategy: 'auto', // Automatically choose the best method
log: true, // Show URL rewriting logs
}
);
// Now your API calls work everywhere!
const users = await api.get('/api/users');
See how easy it is to integrate with your existing code
| Platform | Original URL | Rewritten URL | Status |
|---|---|---|---|
| iOS Simulator | localhost:8000 |
localhost:8000 |
β Works |
| Android Emulator | localhost:8000 |
10.0.2.2:8000 |
β Works |
| Physical iOS Device | localhost:8000 |
192.168.1.100:8000 |
β Works |
| Physical Android Device | localhost:8000 |
192.168.1.100:8000 |
β Works |
See how the proxy automatically adapts to different platforms
iOS Simulator working with localhost
Android Emulator working with 10.0.2.2
Physical device working with IP address
Wraps your API client with automatic URL rewriting.
Parameters:
- `apiClient: Your API client (axios, fetch, etc.)
options: Configuration object
Options:
{
strategy: 'auto' | 'lan' | 'tunnel', // URL rewriting strategy
log: boolean, // Enable logging
baseURL: string, // Base URL to rewrite
}Creates a fetch wrapper with automatic URL rewriting.
Parameters:
options: Configuration object (same as above)
import { withDevProxy } from 'react-native-dev-proxy';
import axios from 'axios';
const api = withDevProxy(
axios.create({
baseURL: 'http://localhost:8000',
timeout: 10000,
}),
{ strategy: 'auto', log: true }
);
// All these work automatically on any platform
const users = await api.get('/api/users');
const user = await api.post('/api/users', { name: 'John' });
const updated = await api.put('/api/users/1', { name: 'Jane' });
const deleted = await api.delete('/api/users/1');import { makeFetch } from 'react-native-dev-proxy';
const fetchApi = makeFetch({
baseURL: 'http://localhost:8000',
strategy: 'auto',
log: true,
});
// Works everywhere
const response = await fetchApi('/api/users');
const data = await response.json();import { useState, useEffect } from 'react';
import { withDevProxy } from 'react-native-dev-proxy';
import axios from 'axios';
const api = withDevProxy(
axios.create({ baseURL: 'http://localhost:8000' }),
{ strategy: 'auto', log: true }
);
const useUsers = () => {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchUsers = async () => {
try {
const response = await api.get('/api/users');
setUsers(response.data);
} catch (error) {
console.error('Failed to fetch users:', error);
} finally {
setLoading(false);
}
};
fetchUsers();
}, []);
return { users, loading };
};auto(recommended): Automatically detects the best methodlan: Always uses your computer's IP addresstunnel: Uses tunneling service (ngrok, etc.)
// Enable detailed logging
const api = withDevProxy(axios, {
strategy: 'auto',
log: true
});
// Console output:
// π§ [DevProxy] Detected platform: android
// π§ [DevProxy] Using strategy: lan
// π§ [DevProxy] Rewriting URL: http://localhost:8000/api/users
// π§ [DevProxy] To: http://192.168.1.100:8000/api/users
// π‘ [DevProxy] Request successful: 200 OKCreate a simple test component:
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { withDevProxy } from 'react-native-dev-proxy';
import axios from 'axios';
const api = withDevProxy(
axios.create({ baseURL: 'http://localhost:8000' }),
{ strategy: 'auto', log: true }
);
const TestComponent = () => {
const [result, setResult] = useState('');
const testAPI = async () => {
try {
const response = await api.get('/api/ping');
setResult(`β
Success: ${JSON.stringify(response.data)}`);
} catch (error) {
setResult(`β Error: ${error.message}`);
}
};
return (
<View style={styles.container}>
<TouchableOpacity style={styles.button} onPress={testAPI}>
<Text style={styles.buttonText}>Test API</Text>
</TouchableOpacity>
<Text style={styles.result}>{result}</Text>
</View>
);
};
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
button: { backgroundColor: '#007AFF', padding: 15, borderRadius: 8 },
buttonText: { color: 'white', fontWeight: 'bold' },
result: { marginTop: 20, textAlign: 'center' },
});
export default TestComponent;
Watch the test component in action across different platforms
const api = withDevProxy(axios, {
baseURL: 'http://localhost:3000', // Your custom server
strategy: 'auto',
log: true,
});const isDevelopment = __DEV__;
const baseURL = isDevelopment
? 'http://localhost:8000'
: 'https://api.yourapp.com';
const api = withDevProxy(axios.create({ baseURL }), {
strategy: isDevelopment ? 'auto' : 'lan',
log: isDevelopment,
});1. "Network request failed" error:
- Ensure your server is running on the correct port
- Check that
adb reverseis set up for Android - Verify your computer and device are on the same network
2. URLs not being rewritten:
- Make sure you're using the wrapped API client
- Check that the patch was applied correctly
- Verify the baseURL matches your server
3. iOS Simulator issues:
- Try using
127.0.0.1instead oflocalhost - Check your server's CORS settings
- Enable logging:
const api = withDevProxy(axios, { log: true });- Check console output:
π§ [DevProxy] Detected platform: android
π§ [DevProxy] Using strategy: lan
π§ [DevProxy] Rewriting URL: http://localhost:8000/api/users
- Test with curl:
curl http://localhost:8000/api/users
See how to debug and fix common issues
Detailed console logging showing URL rewriting
Patch command successfully configuring your project
Easy integration in your code editor
Visual representation of how the proxy works
Comprehensive error handling and debugging
Check out our examples repository for:
- Complete React Native app examples
- Different API client integrations
- Testing setups
- Production configurations
We welcome contributions! Please see our Contributing Guide for details.
MIT License - see LICENSE file for details.
- React Native community for the amazing platform
- Contributors who helped make this package better
- All the developers who faced this problem before us
- π Documentation
- π Issues
- π¬ Discussions
- π§ Email Support
Made with β€οΈ for the React Native community