30+ production-ready React hooks — zero dependencies, TypeScript-first, copy-paste friendly.

| Hook |
Description |
useLocalStorage<T> |
Persist state to localStorage with cross-tab sync |
useDebounce<T> |
Debounce a rapidly-changing value |
useDebouncedCallback |
Debounce a callback function |
useToggle |
Boolean state with toggle / on / off |
| Hook |
Description |
useIntersectionObserver |
Detect when element enters viewport |
useMediaQuery |
Reactive CSS media query matching |
useBreakpoint |
Tailwind-compatible breakpoint detection |
useClipboard |
Copy text with "copied!" feedback state |
useClickOutside |
Detect clicks outside an element |
useKeyPress |
Detect when a specific key is held |
useHotkey |
Register keyboard shortcuts with modifiers |
| Hook |
Description |
useFetch<T> |
Data fetching with loading/error/abort/retry |
| Hook |
Description |
useThrottle<T> |
Throttle a rapidly-changing value |
useThrottledCallback |
Throttle a callback function |
git clone https://github.com/bhupendra05/react-hooks-library.git
# Copy any hook file directly into your project
const [theme, setTheme, clearTheme] = useLocalStorage("theme", "light");
// Cross-tab sync included — change in one tab, updates in all others
const [query, setQuery] = useState("");
const debouncedQuery = useDebounce(query, 300);
useEffect(() => {
if (debouncedQuery) fetchResults(debouncedQuery);
}, [debouncedQuery]);
const { data, status, error, refetch } = useFetch<User[]>("/api/users", {
retries: 3, // retry on failure with exponential backoff
});
if (status === "loading") return <Spinner />;
if (status === "error") return <Error message={error.message} />;
return <UserList users={data} />;
// Lazy-load images, trigger animations, infinite scroll
const { ref, isIntersecting } = useIntersectionObserver({
threshold: 0.1,
freezeOnceVisible: true, // stop observing after first appearance
});
return <img ref={ref} src={isIntersecting ? src : undefined} />;
const { copy, copied } = useClipboard({ timeout: 2000 });
return (
<button onClick={() => copy(codeSnippet)}>
{copied ? "✓ Copied!" : "Copy"}
</button>
);
// ⌘K / Ctrl+K to open search
useHotkey("k", { meta: true }, () => openCommandPalette());
// Escape to close modal
const isEsc = useKeyPress("Escape");
useEffect(() => { if (isEsc) closeModal(); }, [isEsc]);
const { isMobile, isMd, isDark } = useBreakpoint();
return (
<nav className={isMobile ? "bottom-nav" : "sidebar"}>
{isDark && <DarkModeIcon />}
</nav>
);
src/
├── hooks/
│ ├── state/
│ │ ├── useLocalStorage.ts
│ │ ├── useDebounce.ts
│ │ └── useToggle.ts
│ ├── ui/
│ │ ├── useIntersectionObserver.ts
│ │ ├── useMediaQuery.ts
│ │ ├── useClipboard.ts
│ │ ├── useClickOutside.ts
│ │ └── useKeyPress.ts
│ ├── async/
│ │ └── useFetch.ts
│ └── performance/
│ └── useThrottle.ts
└── index.ts
MIT © bhupendra05