Skip to content
Zap Studio
react-hooks
Esc
navigateopen⌘Jpreview
On this page

react-hooks

Small, focused, tree-shakeable React hooks — one hook, one subpath, no forced bundle.

react-hooks is a collection of 100+ small, focused React hooks. Each hook ships as its own subpath export — importing one never pulls in unrelated hooks — with SSR-safe defaults and 100% test coverage.

Motivation

Reaching a browser API from React usually means hand-writing a useEffect — a resize listener, a matchMedia subscription, an IntersectionObserver — and each one carries the same two risks: forget the cleanup and you get a leaked listener that keeps firing after unmount, or forget to guard window/document/navigator and the same code throws on the server or hydrates to a value the client’s first render did not have.

react-hooks wraps these APIs — IntersectionObserver, ResizeObserver, the Battery/Geolocation/Share/Wake Lock APIs, matchMedia, and more — behind a small, correct React interface instead of code you write from scratch. Every hook is SSR- and hydration-safe: nothing touches window, document, or navigator outside an effect or a guarded check, so server renders never throw and hydration never mismatches.

Every hook also ships as its own standalone, side-effect-free module — import it on its own and it tree-shakes cleanly. Public hooks never import each other; some share small internal helper modules, so pulling in useIsMobile never drags in unrelated hook code.

Conventions

  • Every hook is available both from the top-level . barrel and from its own subpath (e.g. @zap-studio/react-hooks/sensors/use-is-mobile) — same function either way.
  • No hook file imports another hook file.

Unstable vs. Experimental

Two different name markers warn about two different kinds of risk:

  • Unstable — the hook reads a private API with no public type, not guaranteed to stay the same shape between React versions. Only useUnstableFiber and useUnstableRenderReason carry this marker, both in Debug / Observability: they walk react-dom’s internal Fiber tree, the same private structure React DevTools itself reads. The risk is about this package breaking on a React upgrade, not about the browser.
  • Experimental — the hook wraps a browser Web API that MDN itself badges “Experimental,” like the Idle Detection API or Web NFC. The hook’s own code is stable; the risk is that the browser API can change or ship in fewer browsers than you’d like. Every useExperimental* hook still fails closed: supported: false (or the equivalent) wherever the underlying API doesn’t exist, instead of throwing.

A hook with neither marker is built entirely on public, standard APIs — safe to treat like any other hook in the package.

Hooks by Category

  • Sensors — viewport, network, device, and permission state (useMediaQuery, useOnlineStatus, useGeolocation, useBattery, …)
  • DOM / Element Interaction — ref’d-element observers and browser chrome APIs (useClickOutside, useIntersectionObserver, useFullscreen, …)
  • Input — keyboard, gamepad, and pointer input (useKeyPress, useHotkeys, useGamepad, …)
  • Media — camera, microphone, and screen capture (useCamera, useMediaRecorder, useSpeechRecognition, …)
  • History & Navigationpopstate and the Navigation API (usePopState, useNavigation, useNavigationBlocker, …)
  • Network — WebSocket and Server-Sent Events (useWebSocket, useEventSource)
  • PWA — installability and service worker state (useInstallPrompt, useServiceWorker, …)
  • Commerce — the Payment Request API (usePaymentRequest)
  • Lifecycle — mount/unmount, timers, and async helpers (useMount, useInterval, useAsync, …)
  • State — local, persisted, and cross-tab state (useLocalStorage, useIndexedDB, useBroadcastChannel, …)
  • Debug / Observability — render diagnostics (useRenderCount, useWhyDidYouUpdate, useUnstableFiber, …)

Learn More

Last updated on September 21, 2026

Was this page helpful?