npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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.

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, or none.
  • 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-info

Bare React Native: you must also have the expo package installed so Expo Modules autolinking works. If you don't yet:

npx install-expo-modules@latest

Then 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: NWPathMonitor reliably reports WiFi/cellular changes, but toggling Personal Hotspot while the default path is unchanged may not fire an event. Call getLocalIp() to force a fresh read when you need certainty.
  • Android hotspot vs. station is resolved by asking ConnectivityManager which interface carries the real TRANSPORT_WIFI (station) network, then treating any other WiFi-family interface with an IP as the hotspot. This correctly handles phones that host the SoftAP on wlan0 itself (not just ap0/swlan0), and devices running WiFi + hotspot concurrently. Use getAllInterfaces() 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.240 fingerprint and NetworkInterface reads 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:android

Then toggle WiFi / your hotspot in Settings and watch the values update live.

License

MIT