Hooks
| Hook | Package | Purpose |
|---|---|---|
useMasonry | @repo/masonry-engine | Memoized masonry with incremental append |
useMasonryWorker | @repo/masonry-engine | Off-main-thread masonry (Web Worker) |
useJustifiedLayout | @repo/justified-layout | Memoized justified layout |
useFixedGrid | @repo/justified-layout | Memoized fixed-aspect grid |
useContainerSize | @repo/ui | ResizeObserver width/height (rAF-coalesced) |
useVirtualGrid | @repo/ui | Windowing over positioned items |
useInfiniteImages | @repo/ui | IntersectionObserver-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.