react-infinite-scroll-hook
A tiny React hook for building infinite-scroll UIs with IntersectionObserver.
Repository Health
Technical Analysis
react-infinite-scroll-hook is a lightweight React hook that wraps the native IntersectionObserver API to trigger infinite loading when a sentry element scrolls into view. Instead of listening to scroll events and doing manual position math, you place a sentry component (often your loading indicator) at the edge of your list and the hook calls onLoadMore when it becomes visible.
It supports both window-level scrolling and scrolling inside a custom container via rootRef, works in either direction (loading more at the bottom, or at the top for chat-style UIs), and exposes simple configuration like rootMargin and a debounce delay to avoid duplicate load triggers.
What You Get
- A single useInfiniteScroll hook with a small, typed API (loading, hasNextPage, onLoadMore, rootMargin, disabled, delayInMs)
- A sentry ref to attach to a loading indicator or list-edge element that triggers loading when visible
- An optional rootRef for scrolling within a custom scrollable container instead of the window
- Built-in debounce (delayInMs) to prevent duplicate onLoadMore calls right after a page finishes loading
- First-class TypeScript types, published as ESM and CJS builds
Common Use Cases
- Infinite-scrolling paginated lists and feeds (e.g. with TanStack Query or SWR)
- Chat-style message boxes that load older messages when scrolling to the top
- Scrollable widgets inside a fixed-height container rather than the page window
- Search results or data tables that load additional pages as the user scrolls
Under The Hood
Architecture The package is a single monorepo member (packages/react-infinite-scroll-hook) built with Turborepo, exporting one hook, useInfiniteScroll, from src/use-infinite-scroll.ts. The hook composes react-intersection-observer-hook’s useTrackVisibility to observe a sentry ref, tracks the latest onLoadMore callback in a ref to avoid stale closures, and derives a shouldLoadMore boolean from loading/disabled/isVisible/hasNextPage before firing a debounced setTimeout call to onLoadMore — a thin, single-purpose composition over IntersectionObserver rather than a from-scratch implementation.
Tech Stack Written in TypeScript, targeting React 19+ as a peer dependency (versions before v6 target older React via ref callback patterns rather than cleanup functions), built with tsup into dual ESM/CJS bundles with generated .d.ts files, and linted/type-checked via a shared @repo/eslint-config and @repo/typescript-config within the Turborepo workspace.
Code Quality The published package has no automated test suite (no test files were found in the packages/react-infinite-scroll-hook directory); confidence in correctness relies on the small (77-line) implementation, TypeScript types, and a live demo app under apps/demo. Naming is clear and the single-file hook has no internal state beyond two refs, keeping the surface easy to audit manually.
API Design The public API is a single hook with five named options (loading, hasNextPage, onLoadMore, rootMargin, disabled, delayInMs) and a two-element return tuple (ref, { rootRef }), mirroring common React hook conventions (e.g. useState-style tuples). Defaults (a 100ms delayInMs) and inline JSDoc-style comments in the type definitions keep the getting-started cost low, though the tuple-of-tuple return shape requires reading the README once to use rootRef correctly.
Used by 2 apps in this directory
APITable
Low Code Platforms · Databases
API-first collaborative spreadsheet-database platform that auto-generates REST APIs and lets teams build internal tools, CRMs, and dashboards without code.
Traefik
Devops · Automation · Security
A cloud-native reverse proxy and load balancer that auto-configures itself from Docker, Kubernetes, and other orchestrators — zero manual routing required.