react-native-local-network-info
v1.0.1
Published
Read a React Native device's own local IPv4 address and whether it is connected to WiFi or acting as a hotspot host, with live network-change events. Built with the Expo Modules API; works in bare React Native and Expo.
Maintainers
Readme
react-native-local-network-info
Read a React Native device's own local IPv4 address and whether it's connected to WiFi or acting as a hotspot host — with live network-change events.
ℹ️ This library only reads your own device's network interfaces. It does not scan, probe, or connect to any other device on the network, and it needs no location permission.
Built with the Expo Modules API, so it works in both bare React Native and Expo apps and supports the New Architecture out of the box.
Why
expo-network / WifiManager.getConnectionInfo() only return the WiFi station IP — they report 0.0.0.0 when the device is the hotspot host. This module reads the device's network interfaces directly, so it returns a usable LAN IP whether the device is a WiFi client or the hotspot, and tells you which.
Features
- ✅ Device's own local IPv4 on the active LAN interface.
- ✅ Role:
wifi,hotspot, ornone. - ✅ WiFi takes precedence when both WiFi and hotspot are active at once.
- ✅ Hotspot host detection that handles Android 11+'s randomized SoftAP subnet (reads the real interface IP — never hardcodes
192.168.43.1). - ✅ Predicted client IP range when the device is a hotspot (iOS: fixed
172.20.10.2–.14; Android: derived from the live subnet). - ✅ Live listener that re-fires on every connectivity / WiFi / hotspot change.
- ✅ A
useLocalIp()React hook. - ✅ No location permission required.
Installation
npm install react-native-local-network-infoBare React Native: you must also have the
expopackage installed so Expo Modules autolinking works. If you don't yet:npx install-expo-modules@latestThen
cd ios && pod install. Expo apps need no extra steps.
Requirements
| | Minimum | | --- | --- | | Expo SDK | 54+ (New Architecture) | | iOS | 15.1 | | Android | API 24 (Android 7.0) |
Permissions
Android permissions are merged automatically via the module's manifest:
ACCESS_NETWORK_STATE— for the change listener & station gateway.ACCESS_WIFI_STATE— for the DHCP gateway fallback.
No ACCESS_FINE_LOCATION and no iOS Info.plist keys are needed — the module only reads its own interfaces (it never connects to or scans other devices).
Usage
import {
getLocalIp,
addNetworkChangeListener,
useLocalIp,
} from 'react-native-local-network-info';
// One-shot read
const info = await getLocalIp();
console.log(info.ip, info.role); // e.g. "192.168.1.42" "wifi"
// Live updates
const sub = addNetworkChangeListener((info) => {
console.log('network changed →', info.role, info.ip);
});
// later: sub.remove();React hook
import { useLocalIp } from 'react-native-local-network-info';
function Status() {
const info = useLocalIp(); // null until first snapshot, then live
if (!info) return <Text>Detecting…</Text>;
return (
<Text>
{info.role === 'hotspot' ? 'Hosting hotspot at' : 'Local IP'}: {info.ip}
</Text>
);
}API
getLocalIp(): Promise<LocalIpInfo>
Captures the current snapshot.
addNetworkChangeListener(cb): EventSubscription
Subscribes to changes. Call .remove() on the returned subscription to unsubscribe.
getAllInterfaces(): Promise<NetworkInterfaceInfo[]>
Every up, non-loopback IPv4 interface with a best-effort role — handy for debugging unusual devices.
useLocalIp(): LocalIpInfo | null
Hook returning the latest snapshot, kept live and auto-cleaned on unmount.
LocalIpInfo
interface LocalIpInfo {
ip: string | null; // device's own local IPv4 (wifi first, then hotspot)
role: 'wifi' | 'hotspot' | 'none'; // wifi wins when both are active
isWifiConnected: boolean;
isHotspotHost: boolean;
interfaceName: string | null; // "en0" | "wlan0" | "bridge100" | "ap0" | ...
netmask: string | null; // "255.255.255.0"
gateway: string | null; // see notes below
predictedClientRange: { first: string; last: string } | null; // hotspot only
platform: 'ios' | 'android' | 'web';
timestamp: number; // epoch ms
}How detection works
| | iOS | Android |
| --- | --- | --- |
| Enumeration | getifaddrs(3) | java.net.NetworkInterface |
| WiFi station | en0 | the interface ConnectivityManager reports for the TRANSPORT_WIFI network (usually wlan0) |
| Hotspot host | bridge* @ 172.20.10.1/28 | any WiFi-family interface (wlan*/ap*/swlan*/softap*) that is not the confirmed station — reads its live IP |
| Cellular (ignored for LAN IP) | pdp_ip0 | rmnet* / ccmni* |
| Change events | NWPathMonitor | registerDefaultNetworkCallback + WIFI_AP_STATE_CHANGED |
| Station gateway | derived from subnet (heuristic) | LinkProperties default route (real) |
Precedence: if a WiFi-station IP exists it is returned with role: 'wifi'; otherwise the hotspot-host IP is returned with role: 'hotspot'; otherwise role: 'none' with ip: null.
Platform notes & limitations
- iOS station gateway is a heuristic (first host of the subnet). Apple exposes no public default-gateway API; the WiFi IP, netmask, and role are accurate.
- iOS hotspot change events:
NWPathMonitorreliably reports WiFi/cellular changes, but toggling Personal Hotspot while the default path is unchanged may not fire an event. CallgetLocalIp()to force a fresh read when you need certainty. - Android hotspot vs. station is resolved by asking
ConnectivityManagerwhich interface carries the realTRANSPORT_WIFI(station) network, then treating any other WiFi-family interface with an IP as the hotspot. This correctly handles phones that host the SoftAP onwlan0itself (not justap0/swlan0), and devices running WiFi + hotspot concurrently. UsegetAllInterfaces()to inspect an unusual device. - Web returns
role: 'none'/ip: null— browsers don't expose the LAN IP. - iOS interface-name → role mapping is a documented heuristic (Apple exposes no public role API); the hotspot-host
172.20.10.1/255.255.255.240fingerprint andNetworkInterfacereads are the reliable signals.
Example app
cd example
npm install
npx expo prebuild # generates ios/ and android/
npx expo run:ios # or: npx expo run:androidThen toggle WiFi / your hotspot in Settings and watch the values update live.
License
MIT
