| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
A react-grid-layout v2 alternative, built on dnd-kit.
Draggable, resizable, responsive grid layouts for React, Svelte, and Vue, with pluggable packing and dragging tiles between grids.
Documentation · Getting Started · Examples · API
Bindings: React · Svelte · Vue
snapgrid keeps the parts of react-grid-layout people rely on — the { i, x, y, w, h } layout model, controlled onLayoutChange, responsive breakpoints — and adds the things it can't do.
| snapgrid | react-grid-layout | |
|---|---|---|
| Layout model ({ i, x, y, w, h }, controlled) | ✅ | ✅ |
| Responsive breakpoints | ✅ | ✅ |
| Resize handles · per-item min/max · static tiles | ✅ | ✅ |
| Drag tiles between grids | ✅ built-in (SnapGridGroup) | ❌ |
| Nested grids | ✅ cross-level dragging | ⚠️ manual |
| dnd-kit interop (sortable lists / boards) | ✅ two-way (snapMove) | ❌ |
| Keyboard dragging / a11y | ✅ Enter · arrows · Esc | ❌ |
| Headless (bring your own markup) | ✅ provider + hooks | ❌ renders its own DOM |
| Pluggable packing | ✅ vertical / horizontal / none + masonry / gravity / shelf + custom | vertical / horizontal / none |
| Accept external draggables | ✅ dropConfig / onDrop | ⚠️ droppingItem |
| Styling | unstyled, ships no CSS | requires react-grid-layout.css + react-resizable.css |
| Interaction engine | dnd-kit, its latest framework-agnostic core (pointer · touch · keyboard) | react-draggable + react-resizable |
| TypeScript types | ✅ bundled | via @types/react-grid-layout |
react-grid-layout is mature, widely deployed, and battle-tested. This table is about capability differences, not quality. snapgrid is new; if you need a proven incumbent today, RGL is a great choice. Coming from it? See the migration guide.
snapgrid itself is ~8 kB brotli, but it's built on dnd-kit (~30 kB), so a fresh install is ~38 kB brotli, roughly 2.5× react-grid-layout v2's ~15 kB (minified, React excluded). That weight is dnd-kit, and it's a deliberate trade:
# React
pnpm add @snapgridjs/react @dnd-kit/react @dnd-kit/dom
# Svelte 5
pnpm add @snapgridjs/svelte @dnd-kit/svelte @dnd-kit/dom
# Vue 3
pnpm add @snapgridjs/vue @dnd-kit/vue @dnd-kit/dom@snapgridjs/extras (masonry/gravity/shelf packers) is optional.
snapgrid is headless-first: you compose hooks with a dnd-kit DragDropProvider and render your own markup. The example below is React. The Svelte API mirrors it with createGridContainer / createGridItem factories and {@attach} (quick start); the Vue API mirrors it with useGridContainer / useGridItem composables and function refs (quick start).
import { DragDropProvider } from "@dnd-kit/react";
import { type Layout, useContainerWidth, useGridContainer, useGridItem } 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 },
]);
// You supply the dnd-kit provider; useGridContainer runs inside it (in Surface).
return (
<div ref={containerRef}>
<DragDropProvider>
<Surface layout={layout} width={width} onLayoutChange={setLayout} />
</DragDropProvider>
</div>
);
}
function Surface({
layout,
width,
onLayoutChange,
}: { layout: Layout; width: number; onLayoutChange: (next: Layout) => void }) {
const { containerProps, group } = useGridContainer({ layout, width, onLayoutChange });
return (
<div {...containerProps}>
{layout.map((it) => (
<Tile key={it.i} id={it.i} group={group} />
))}
</div>
);
}
function Tile({ id, group }: { id: string; group: string }) {
const { ref, style } = useGridItem({ id, group });
return (
<div ref={ref} style={style} className="tile">
{id}
</div>
);
}Prefer a ready-made component? The turnkey <GridLayout> wraps these same hooks (and supplies the provider) in a react-grid-layout-style API — drop in keyed children and you're done:
<GridLayout layout={layout} width={width} onLayoutChange={setLayout}>
{layout.map((item) => (
<div key={item.i} className="tile">{item.i}</div>
))}
</GridLayout>→ Full walkthrough in Getting Started.
| Package | Description |
|---|---|
| @snapgridjs/react | React components + hooks. The main entry point for React. |
| @snapgridjs/svelte | Svelte 5 components + factories. The main entry point for Svelte. |
| @snapgridjs/vue | Vue 3 components + composables. The main entry point for Vue. |
| @snapgridjs/core | Framework-agnostic layout math (geometry, move/resize, compaction, drag-session). |
| @snapgridjs/dnd | Framework-agnostic dnd-kit engine (drag/resize/cross-grid/interop) the bindings build on. Comes in with @snapgridjs/react; for binding authors. |
| @snapgridjs/extras | Optional packers: masonry, gravity, shelf, wrap. |
This is a pnpm workspace.
pnpm install # install everything
pnpm dev # run the docs site (apps/docs) — guides, live examples, showcase
pnpm validate # typecheck + lint + test + build| Command | Does |
|---|---|
| pnpm test | Run the Vitest suite. |
| pnpm lint / pnpm lint:fix | Biome check / autofix. |
| pnpm typecheck | Type-check every package. |
| pnpm build | Build all packages. |
See CONTRIBUTING.md before opening a PR.
snapgrid stands on the shoulders of dnd-kit (the interaction layer) and react-grid-layout (whose core packing engine it adapts).
MIT © Edmond Leung
| Back | FazBrowse Home | New Git URL |