react-grid-layout alternative · dnd-kit powered
Grids that drag, resize, and repack.
A controlled, headless-first grid layout for React: draggable and resizable tiles, pluggable packing, responsive breakpoints, and dragging tiles between grids. Built on dnd-kit.
Why snapgrid
Controlled & predictable
You own the layout array. Every drag, resize, and cross-grid move comes back through onLayoutChange. No hidden internal state.
Learn more →Headless or drop-in
Use <GridLayout> for the common case, or compose SnapGridProvider + hooks and render your own markup. No imposed DOM or CSS.
Learn more →Pluggable packing
Vertical, horizontal, or free. Plus masonry, gravity, and shelf packers, or bring your own Compactor.
Learn more →Cross-grid dragging
Wrap grids in a <SnapGridGroup> and drag tiles between them. The source loses the tile; the destination gains it.
Learn more →Nested grids
Drop a grid inside a tile of another grid. Standalone providers keep each level isolated: drag the panel, or rearrange what's inside it.
Learn more →Responsive
Per-breakpoint layouts with <ResponsiveGridLayout>; missing breakpoints are generated from the nearest one.
Learn more →Resizable, with limits
Any edge or corner, with per-item minW/maxW/minH/maxH honored and static tiles that never move.
Learn more →Keyboard accessible
Every tile is keyboard-draggable: focus, pick up with Enter, move with the arrow keys, drop or cancel with Escape. No extra wiring.
Learn more →Coming from react-grid-layout?
snapgrid keeps everything you rely on in RGL — the same controlled layout model, onLayoutChange, responsive breakpoints, resize limits, and static tiles — and adds cross-grid dragging, nested grids, a headless mode, and keyboard-accessible dragging. The real difference is the engine underneath: snapgrid runs on dnd-kit, the de-facto standard for drag-and-drop in React.
- Already using dnd-kit? snapgrid slots into your existing interaction layer, and adds only its own ~6 kB on top of the dnd-kit you already ship.
- Accessibility RGL lacks. dnd-kit gives every tile keyboard dragging and screen-reader support out of the box; react-draggable / react-resizable don't.
- Modern, maintained input. One pointer · touch · keyboard sensor model instead of RGL's older handlers.
A 30-second example
import { GridLayout, useContainerWidth, type Layout } from "@snapgridjs/react";
import { useState } from "react";
export function Board() {
const { width, containerRef } = useContainerWidth();
const [layout, setLayout] = useState<Layout>([
{ i: "a", x: 0, y: 0, w: 4, h: 2 },
{ i: "b", x: 4, y: 0, w: 4, h: 2 },
{ i: "c", x: 8, y: 0, w: 4, h: 2 },
]);
return (
<div ref={containerRef}>
<GridLayout layout={layout} width={width} onLayoutChange={setLayout}>
{layout.map((item) => (
<div key={item.i} className="tile">{item.i}</div>
))}
</GridLayout>
</div>
);
}