Getting Started with Allem SDK Hooks: 8 Essential React Hooks
Learn how to use @allem-sdk/hooks — 8 SSR-safe React hooks for debouncing, local storage, media queries, clipboard, intersection observer, and more.

@allem-sdk/hooks provides 8 essential React hooks for common UI patterns. Every hook is SSR-safe, TypeScript-first, and has zero dependencies beyond React.
Installation
npm install @allem-sdk/hooks
Or install everything with the meta-package:
npm install allem-sdk
useDebounce
Debounce any value with a configurable delay. Useful for search inputs and API calls:
import { useState, useEffect } from "react";
import { useDebounce } from "@allem-sdk/hooks";
function SearchInput() {
const [search, setSearch] = useState("");
const debouncedSearch = useDebounce(search, 300);
useEffect(() => {
if (debouncedSearch) {
fetchResults(debouncedSearch);
}
}, [debouncedSearch]);
return (
<input
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search..."
/>
);
}
The second argument is the delay in milliseconds (default: 500).
useClickOutside
Detect clicks outside a referenced element. Perfect for closing dropdowns and popovers:
import { useRef, useState } from "react";
import { useClickOutside } from "@allem-sdk/hooks";
function Dropdown() {
const ref = useRef<HTMLDivElement>(null);
const [isOpen, setIsOpen] = useState(false);
useClickOutside(ref, () => setIsOpen(false));
return (
<div ref={ref}>
<button onClick={() => setIsOpen(true)}>Menu</button>
{isOpen && (
<ul className="absolute bg-white shadow-lg rounded-md p-2">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
)}
</div>
);
}
useLocalStorage
Persist state in localStorage with automatic JSON serialization. SSR-safe — returns the initial value on the server:
import { useLocalStorage } from "@allem-sdk/hooks";
function Settings() {
const [theme, setTheme] = useLocalStorage("theme", "light");
const [fontSize, setFontSize] = useLocalStorage("fontSize", 16);
return (
<div>
<button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
Theme: {theme}
</button>
<input
type="range"
min={12}
max={24}
value={fontSize}
onChange={(e) => setFontSize(Number(e.target.value))}
/>
</div>
);
}
useToggle
Boolean state with named helper functions instead of manual setState:
import { useToggle } from "@allem-sdk/hooks";
function Panel() {
const { value: isOpen, toggle, on, off } = useToggle();
return (
<div>
<button onClick={toggle}>{isOpen ? "Close" : "Open"}</button>
{isOpen && (
<div className="p-4 border rounded">
<p>Panel content</p>
<button onClick={off}>Dismiss</button>
</div>
)}
</div>
);
}
The on and off functions are stable references, safe to pass as callbacks.
useCopyToClipboard
Copy text to the clipboard with automatic success state that resets after 2 seconds:
import { useCopyToClipboard } from "@allem-sdk/hooks";
function CopyButton() {
const { copied, copy } = useCopyToClipboard();
return (
<button onClick={() => copy("npm install allem-sdk")}>
{copied ? "Copied!" : "Copy install command"}
</button>
);
}
useMediaQuery
Track CSS media query matches reactively. SSR-safe — returns false on the server:
import { useMediaQuery } from "@allem-sdk/hooks";
function ResponsiveLayout() {
const isMobile = useMediaQuery("(max-width: 768px)");
const prefersDark = useMediaQuery("(prefers-color-scheme: dark)");
return (
<div>
{isMobile ? <MobileNav /> : <DesktopNav />}
{prefersDark && <p>You prefer dark mode</p>}
</div>
);
}
useWindowSize
Track window dimensions reactively. SSR-safe — returns 0 for both values on the server:
import { useWindowSize } from "@allem-sdk/hooks";
function WindowInfo() {
const { width, height } = useWindowSize();
return (
<div>
<p>Window: {width} x {height}</p>
{width < 768 && <p>Mobile viewport detected</p>}
</div>
);
}
useIntersectionObserver
Observe whether an element is visible in the viewport. Useful for lazy loading, infinite scroll, and scroll-triggered animations:
import { useRef } from "react";
import { useIntersectionObserver } from "@allem-sdk/hooks";
function AnimateOnScroll() {
const ref = useRef<HTMLDivElement>(null);
const isVisible = useIntersectionObserver(ref, { threshold: 0.5 });
return (
<div
ref={ref}
className={`transition-all duration-500 ${
isVisible ? "opacity-100 translate-y-0" : "opacity-0 translate-y-4"
}`}
>
This content fades in when scrolled into view.
</div>
);
}
The threshold option controls how much of the element must be visible (0 to 1).
Quick Reference
| Hook | Returns | SSR-Safe |
|---|---|---|
useDebounce(value, delay) |
Debounced value | Yes |
useClickOutside(ref, handler) |
— | Yes |
useLocalStorage(key, initial) |
[value, setValue] |
Yes |
useToggle(initial?) |
{ value, toggle, on, off } |
Yes |
useCopyToClipboard() |
{ copied, copy } |
Yes |
useMediaQuery(query) |
boolean |
Yes |
useWindowSize() |
{ width, height } |
Yes |
useIntersectionObserver(ref, opts) |
boolean |
Yes |
What's Next
- Explore Allem SDK Forms for form validation hooks
- Try Allem SDK AI for chat and completion hooks
- Read the full hooks documentation
Enjoyed this article?
I write about building products, AI, aviation, and the journey of entrepreneurship. Follow along for more.
Keep reading

Getting Started with Allem UI Date Picker: Accessible Calendars for React
Learn how to set up @allem-ui/date-picker with Calendar, DatePicker, DateRangePicker, and TimeField components built on React Aria.

Getting Started with Allem UI Data Grid: Sortable, Filterable Tables for React
Learn how to set up @allem-ui/data-grid with TanStack Table to build sortable, filterable, and paginated data tables in React.

Getting Started with Allem UI React: Build Accessible Interfaces in Minutes
Learn how to install @allem-ui/react, set up Tailwind CSS v4, and build your first accessible interface with 30+ production-ready components.