ahmedallem.
Engineering · 3 min read

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.

Ahmed Allem

Ahmed Allem

Founder & CTO · Aviation, AI & Startups

ShareShare
Getting Started with Allem SDK Hooks: 8 Essential React Hooks

@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