DEV Community

reactuse.com
reactuse.com

Posted on • Originally published at reactuse.com

10 Browser API Hooks Every React Developer Needs

Modern browsers ship with powerful APIs for geolocation, clipboard access, fullscreen mode, network status, and more. Using them directly in React is harder than it should be. You need to guard against server-side rendering, add and remove event listeners, handle permissions, and clean up on unmount. Multiply that by every browser API your app touches and you have a lot of repetitive, error-prone code.

ReactUse solves this with a library of 100+ hooks that wrap browser APIs into clean, SSR-safe, TypeScript-friendly interfaces. Every hook listed below checks for browser availability before accessing any API, so it works out of the box with Next.js, Remix, and any other SSR framework. Install once and import what you need:

npm i @reactuses/core
Enter fullscreen mode Exit fullscreen mode

1. useMediaQuery -- Responsive Design

Respond to CSS media queries in JavaScript. The hook returns a boolean that updates in real time when the viewport changes.

import { useMediaQuery } from "@reactuses/core";

function App() {
  const isMobile = useMediaQuery("(max-width: 768px)");
  return <div>{isMobile ? <MobileNav /> : <DesktopNav />}</div>;
}
Enter fullscreen mode Exit fullscreen mode

Use it to conditionally render layouts, load different assets, or toggle features based on screen size without relying on CSS alone.

2. useClipboard -- Copy to Clipboard

Read from and write to the system clipboard using the modern Clipboard API. The hook handles permissions, HTTPS requirements, and focus-state edge cases.

import { useClipboard } from "@reactuses/core";

function CopyButton({ text }: { text: string }) {
  const [clipboardText, copy] = useClipboard();
  return (
    <button onClick={() => copy(text)}>
      {clipboardText === text ? "Copied!" : "Copy"}
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

3. useGeolocation -- User Location

Track the user's geographic coordinates with automatic cleanup of the watchPosition listener on unmount.

import { useGeolocation } from "@reactuses/core";

function LocationDisplay() {
  const { coordinates, error, isSupported } = useGeolocation();
  if (!isSupported) return <p>Geolocation is not supported.</p>;
  if (error) return <p>Error: {error.message}</p>;
  return (
    <p>Lat: {coordinates.latitude}, Lng: {coordinates.longitude}</p>
  );
}
Enter fullscreen mode Exit fullscreen mode

4. useFullscreen -- Fullscreen Mode

Toggle fullscreen on any element. The hook wraps the Fullscreen API and returns the current state along with control functions.

import { useRef } from "react";
import { useFullscreen } from "@reactuses/core";

function VideoPlayer() {
  const ref = useRef<HTMLDivElement>(null);
  const [isFullscreen, { enterFullscreen, exitFullscreen, toggleFullscreen }] =
    useFullscreen(ref);
  return (
    <div ref={ref}>
      <video src="/demo.mp4" />
      <button onClick={toggleFullscreen}>
        {isFullscreen ? "Exit" : "Fullscreen"}
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

5. useNetwork -- Online/Offline Status

Monitor the user's network connection. The hook tracks online/offline state and, where available, connection details like effectiveType and downlink.

import { useNetwork } from "@reactuses/core";

function NetworkBanner() {
  const { online, effectiveType } = useNetwork();
  if (!online) return <div className="banner">You are offline</div>;
  return <div>Connection: {effectiveType}</div>;
}
Enter fullscreen mode Exit fullscreen mode

6. useIdle -- Idle Detection

Detect when the user has stopped interacting with the page. The hook listens for mouse, keyboard, touch, and visibility events and returns true after the specified timeout.

import { useIdle } from "@reactuses/core";

function IdleWarning() {
  const isIdle = useIdle(300_000); // 5 minutes
  return isIdle ? <div>Are you still there?</div> : null;
}
Enter fullscreen mode Exit fullscreen mode

7. useDarkMode -- Dark Mode Toggle

Manage dark mode with system preference detection, localStorage persistence, and automatic class toggling on the root element.

import { useDarkMode } from "@reactuses/core";

function ThemeToggle() {
  const [isDark, toggle] = useDarkMode({
    classNameDark: "dark",
    classNameLight: "light",
  });
  return (
    <button onClick={toggle}>
      {isDark ? "Switch to Light" : "Switch to Dark"}
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

8. usePermission -- Permission Status

Query the status of a browser permission (geolocation, camera, microphone, notifications, and others) and react to changes in real time.

import { usePermission } from "@reactuses/core";

function CameraAccess() {
  const status = usePermission("camera");
  if (status === "denied") return <p>Camera access was denied.</p>;
  if (status === "prompt") return <p>We need camera permission.</p>;
  return <p>Camera access granted.</p>;
}
Enter fullscreen mode Exit fullscreen mode

9. useLocalStorage -- Persistent State

A drop-in replacement for useState that persists to localStorage. It handles serialization, SSR safety, cross-tab sync via the storage event, and error recovery.

import { useLocalStorage } from "@reactuses/core";

function Settings() {
  const [lang, setLang] = useLocalStorage("language", "en");
  return (
    <select value={lang ?? "en"} onChange={(e) => setLang(e.target.value)}>
      <option value="en">English</option>
      <option value="es">Spanish</option>
      <option value="fr">French</option>
    </select>
  );
}
Enter fullscreen mode Exit fullscreen mode

10. useEventListener -- Event Handling

Attach event listeners to any target (window, document, or a specific element) with automatic cleanup and TypeScript-safe event types.

import { useEventListener } from "@reactuses/core";

function KeyLogger() {
  useEventListener("keydown", (event) => {
    console.log("Key pressed:", event.key);
  });
  return <p>Press any key...</p>;
}
Enter fullscreen mode Exit fullscreen mode

This is the foundational hook that many other hooks in ReactUse are built on. It avoids stale closures by always referencing the latest handler.

Manual Implementation vs. ReactUse

Every hook above replaces a significant amount of boilerplate:

Concern Manual Implementation ReactUse Hook
SSR safety checks typeof window !== "undefined" guards everywhere Built in
Event listener cleanup useEffect return with removeEventListener Automatic
TypeScript event types Manual generic constraints per event Fully typed
Permission handling navigator.permissions.query + state management Single call
localStorage serialization JSON.parse / JSON.stringify + error handling Automatic
Cross-tab sync Manual storage event listener Built in

For a single hook the savings are modest. Across an entire application using five or more browser APIs, ReactUse eliminates hundreds of lines of defensive code.

FAQ

Are these hooks SSR-safe?

Yes. Every hook in ReactUse checks for browser availability before accessing any API. During server-side rendering, hooks return safe default values and skip browser-only logic.

Can I tree-shake unused hooks?

Yes. Importing from @reactuses/core supports tree-shaking. Your bundler will only include the hooks you actually import.

Do these hooks work with React 18 and 19?

ReactUse supports React 16.8 and above. All hooks are compatible with React 18 concurrent features and React 19.


ReactUse provides 100+ hooks for React. Explore them all →

Top comments (0)