@usefy/use-network-state
v0.25.1
Published
A React hook for tracking online/offline status and the Network Information API (effectiveType, downlink, saveData) with SSR support
Downloads
1,054
Maintainers
Readme
Overview
useNetworkState is part of the @usefy ecosystem — a collection of production-ready, TypeScript-first, SSR-safe React hooks. It combines navigator.onLine with the Network Information API (navigator.connection) to give you a single, reactive snapshot of the device's connectivity and connection quality.
Features
- Online / offline —
navigator.onLine, updated on the windowonline/offlineevents, with asincetimestamp of the last transition - Network Information —
effectiveType,downlink,downlinkMax,rtt,saveData,typefromnavigator.connection(withmozConnection/webkitConnectionfallback), updated on itschangeevent - Graceful degradation — every Network Information field is
undefinedwhere the API is unsupported (Firefox, Safari);onlinealways works and the hook never throws - SSR-safe & concurrent-safe — built on
useSyncExternalStore; returns a deterministic{ online: true }on the server, so there is no hydration mismatch - TypeScript-first — full type inference and exported types (including the
EffectiveConnectionTypeandConnectionTypeunions) - Tiny & tree-shakeable — zero dependencies, published as its own package
Installation
# npm
npm install @usefy/use-network-state
# yarn
yarn add @usefy/use-network-state
# pnpm
pnpm add @usefy/use-network-stateRequires React 18 or 19 (peerDependencies: "react": "^18.0.0 || ^19.0.0").
Quick Start
import { useNetworkState } from "@usefy/use-network-state";
function ConnectivityBanner() {
const { online } = useNetworkState();
if (online) return null;
return <div role="alert">You are offline.</div>;
}Adapt behaviour to connection quality:
import { useNetworkState } from "@usefy/use-network-state";
function Hero() {
const { effectiveType, saveData } = useNetworkState();
const lowData = saveData || effectiveType === "slow-2g" || effectiveType === "2g";
return lowData ? <LowResImage /> : <HighResImage />;
}API
useNetworkState(): NetworkState
Takes no arguments and returns the current network state. The object identity is stable between updates that don't change any observed value (safe as an effect dependency).
NetworkState
| Field | Type | Description |
| --------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| online | boolean | From navigator.onLine. Defaults to true on the server / without a navigator. |
| since | Date \| undefined | Timestamp of the last online/offline transition. undefined until the first transition occurs. |
| downlink | number \| undefined | Estimated downlink speed in Mb/s. |
| downlinkMax | number \| undefined | Maximum downlink speed of the underlying technology, in Mb/s. |
| effectiveType | "slow-2g" \| "2g" \| "3g" \| "4g" \| undefined | Effective connection type. |
| rtt | number \| undefined | Estimated effective round-trip time in ms. |
| saveData | boolean \| undefined | Whether the user has requested reduced data usage ("Data Saver"). |
| type | ConnectionType \| undefined | Physical connection type ("wifi", "cellular", "ethernet", …). |
All fields except online are undefined when the Network Information API is
unsupported.
Exported types & helpers
import {
useNetworkState,
getNetworkState, // read a one-off snapshot outside React
getConnection, // resolve navigator.connection (+ vendor prefixes)
isNavigatorAvailable, // SSR guard
isNetworkInformationSupported, // feature detection
areNetworkStatesEqual, // field-by-field comparison
SERVER_NETWORK_STATE, // the inert server snapshot ({ online: true })
type NetworkState,
type UseNetworkStateReturn,
type EffectiveConnectionType,
type ConnectionType,
type NetworkInformationLike,
} from "@usefy/use-network-state";Browser Support
- Online/offline (
online,since) works everywhere. - Network Information fields require a Chromium-based browser
(Chrome, Edge, Opera, most Android browsers). Firefox and Safari do not
implement the API, so those fields are
undefined— always treat them as optional.
Testing
📊 View Detailed Coverage Report (GitHub Pages) — 34 tests, 95% statement coverage.
License
MIT © mirunamu
This package is part of the usefy monorepo.
