About these React snippets
This is a collection of the React hooks and helpers I actually reuse across real Next.js apps, including this portfolio. Everything here is TypeScript-first, SSR-safe where it matters, and written to work with modern React (18 and 19) and the Next.js App Router. No class components, no legacy patterns.
Each snippet is deliberately tiny: usually 30 to 80 lines of code you can read in one pass, understand, and paste straight into your project. There is no @rabi/react-utils package to install, because experience has taught me that the best small utilities are the ones you own outright. You can tweak them, delete them, or grow them without fighting a maintainer's opinion.
What's inside
useDebounce: debounce any rapidly changing value (search inputs, resize events, filters) with a single line of code.useIntersectionObserver: declarative viewport tracking for fade-in animations, lazy loading, and infinite scroll.useScrollProgress: a passive scroll-progress hook for reading progress bars and scroll-linked effects.useLocalStorage: typed, SSR-safe state that persists tolocalStorage, with cross-tab sync.useClickOutside,useCopyToClipboard,useKeyboardShortcut,useOnlineStatus: the small hooks you end up needing on nearly every project.
More hooks land here as I extract them from client work and this site's own components. If you are curious about what is coming next, the blog usually covers the deeper "why" behind a hook before it shows up here.
How to use them
Every snippet page shows the full source plus a minimal usage example. Copy the hook, drop it in src/hooks/, and import it. That is the whole workflow. The code is intentionally small enough to read in under a minute, so you can adapt it to your own naming conventions, styling system, or state library without fighting a generic API.
A few things I try to get right on every hook:
- SSR safety: every hook guards
window,document, andlocalStorageaccess so it does not break Next.js server rendering or hydration. - Cleanup: event listeners and observers are always torn down in the
useEffectcleanup, so there is no memory leak when a component unmounts. - Passive listeners: scroll and touch handlers use
{ passive: true }whenever they do not callpreventDefault, so the main thread stays free.
If you spot a bug or a cleaner version, the code is open on GitHub. Issues and PRs are welcome.