Skip to content

eleung/snapgrid

snapgrid

A react-grid-layout v2 alternative, built on dnd-kit.

Draggable, resizable, responsive grid layouts for React, with pluggable packing and dragging tiles between grids.

License: MIT npm bundle size CI types

Documentation · Getting Started · Examples · API


Dragging a tile from one grid into another, the rest of the tiles compacting to make room

Why snapgrid

  • Controlled & predictable: you own the layout array; every change comes back through onLayoutChange. No hidden state.
  • Headless or drop-in: <GridLayout> for the common case, or SnapGridProvider + hooks for full control of the markup. Ships no CSS.
  • Pluggable packing: vertical / horizontal / none, plus masonry / gravity / shelf from @snapgridjs/extras, or your own Compactor.
  • Cross-grid dragging: wrap grids in a <SnapGridGroup> and drag tiles between them.
  • Nested grids: drop a grid inside a tile of another grid; each level keeps its own isolated drag session.
  • Responsive: per-breakpoint layouts with <ResponsiveGridLayout>.
  • Resizable, with limits: any edge/corner, per-item minW/maxW/minH/maxH, and static tiles.
  • Keyboard accessible: every tile is keyboard-draggable — Enter/Space to pick up, arrow keys to move, Esc to cancel.
  • SSR-safe and TypeScript-first (types included).

snapgrid vs react-grid-layout

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 ✅ isolated per level ⚠️ manual
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.

Bundle size, honestly

snapgrid itself is ~6 kB brotli, but it's built on dnd-kit (~27 kB), so a fresh install is ~33 kB brotli, roughly 2× react-grid-layout v2's ~15 kB (minified, React excluded). That weight is dnd-kit, and it's a deliberate trade:

  • dnd-kit is the de-facto standard for drag-and-drop in React. Its accessible, multi-sensor engine is what gives snapgrid keyboard dragging, touch support, and cross-grid out of the box (things RGL's older react-draggable/react-resizable stack doesn't).
  • If your app already uses dnd-kit, snapgrid adds only ~6 kB.
  • snapgrid tracks dnd-kit's latest framework-agnostic line (@dnd-kit/react), the line dnd-kit recommends over the legacy @dnd-kit/core.

Install

pnpm add @snapgridjs/react @dnd-kit/react @dnd-kit/dom

@snapgridjs/extras (masonry/gravity/shelf packers) is optional.

Quick start

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>
  );
}

→ Full walkthrough in Getting Started.

Packages

Package Description
@snapgridjs/react React components + hooks. The main entry point.
@snapgridjs/core Framework-agnostic layout engine (geometry, move/resize, compaction).
@snapgridjs/extras Optional packers: masonry, gravity, shelf, wrap.

Development

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.

Acknowledgements

snapgrid stands on the shoulders of dnd-kit (the interaction layer) and react-grid-layout (whose core packing engine it adapts).

License

MIT © Edmond Leung

About

snapgrid is a react-grid-layout v2 alternative built on dnd-kit. Drag, resize, repack, and drag between grids.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors