Skip to content
DocsReferenceHooks

Hooks

HookPackagePurpose
useMasonry@repo/masonry-engineMemoized masonry with incremental append
useMasonryWorker@repo/masonry-engineOff-main-thread masonry (Web Worker)
useJustifiedLayout@repo/justified-layoutMemoized justified layout
useFixedGrid@repo/justified-layoutMemoized fixed-aspect grid
useContainerSize@repo/uiResizeObserver width/height (rAF-coalesced)
useVirtualGrid@repo/uiWindowing over positioned items
useInfiniteImages@repo/uiIntersectionObserver-driven background paging

Putting it together

A complete masonry feed is four hooks and a renderer:

const { ref, width } = useContainerSize<HTMLDivElement>();
 
const { images, sentinelRef } = useInfiniteImages({
  initial,
  fetchPage: (page, size) => fetchImagePage(page, size, seed),
});
 
const { positions, containerHeight } = useMasonry(images, { containerWidth: width });
 
return (
  <div ref={ref}>
    <VirtualCanvas
      positions={positions}
      containerHeight={containerHeight}
      overscan={500}
      sentinel={<div ref={sentinelRef} />}
      renderItem={(item, priority) => (
        <ImageTile item={item} priority={priority} sizes={`${item.width}px`} />
      )}
    />
  </div>
);

useContainerSize

const { ref, width, height } = useContainerSize<HTMLDivElement>();

Measures an element with a ResizeObserver, coalescing bursts to one update per frame. Layout recomputes downstream the instant the width crosses a breakpoint.

useVirtualGrid

const { containerRef, visible } = useVirtualGrid({
  positions,
  containerHeight,
  overscan: 500,
  adaptiveOverscan: true,
  onSample: (s) => { sampleRef.current = s; }, // visibleCount, velocity, overscan
});

Returns only the items in view (+ overscan). The onSample callback writes to a ref (never triggers a render) and feeds the benchmark HUD.