Masonry Kit
Framework-agnostic masonry/bento grid layout engine — ResizeObserver-measured, transform-positioned, with bento-style colSpan/rowSpan cards built in from the start, not bolted on later. Vue 3, React, and Nuxt adapters share one core. You own the card markup and content; this only measures it and packs it.
Features
- Skyline packing generalized to spans — classic shortest-lane masonry, extended to bento-style
colSpan/rowSpancards from the first line of code, not bolted on afterward;'balanced'(default) picks the least-filled lane group for each item,'ordered'keeps strict round-robin instead - One axis-agnostic engine for both directions —
direction: 'vertical'(columns) and'horizontal'(rows) share the same core geometry, not two separate algorithms to keep in sync - Transform-based positioning, not CSS
columns/Grid masonry — every item is measured viaResizeObserverand placed withtransform: translate(), so a reflow never triggers layout of its own, and an image's height changing afterloadre-packs the grid automatically - Virtualization built in — a two-phase layout for large lists: items outside the visible range (± overscan) skip real DOM measurement entirely and use an estimated size instead, so relayout stays cheap regardless of list size
- FLIP-animated reflow — items slide into their new slot instead of teleporting, and fade in/out on add/remove, entirely via inline styles (zero required CSS)
- SSR-safe — a CSS
columnsapproximation renders before the engine exists (server-side, and for the one client frame before the first real measurement), then swaps to the exact layout in the same frame it measures - Keyboard-reorderable items — pick up/move/drop via space and arrow keys, announced through a live region; pointer/touch drag was tried and deliberately left out — masonry's skyline packing makes a live pointer-drag reflow inherently unpredictable (which neighbor ends up where depends on the exact path the cursor took, not just where it landed) in a way a discrete keyboard step isn't
- Vue, React, and Nuxt adapters over one core — a
<MasonryGrid>component/hook pair for each framework, all re-exporting the full core surface, so installing just one adapter package reaches the framework-agnostic layer too - Zero peer dependencies in core —
@macrulez/masonry-kit-coreruns anywhere, including outside a framework entirely