React Grid Layout logo

React Grid Layout

A draggable and resizable grid layout system for React with responsive breakpoints and collision detection.

npm install react-grid-layout
21.7K1.3M/weekv1.5.2496.1 KBMIT251 issues
Last updated: 2025-06-26
Star history chart for react-grid-layout/react-grid-layout

TL;DR

The Standard for Dashboards: The go-to library for building interactive, user-customizable grid interfaces where widgets can be dragged, resized, and auto-packed.

Physics & Geometry: Uses absolute positioning and JavaScript calculations to manage layout state, enabling features like gravity-like compaction and collision handling.

Why React Grid Layout?

React Grid Layout (RGL) solves a very specific but difficult problem: allowing users to arrange boxes on a screen freely while maintaining a structured grid. It replicates the "masonry" or "dashboard" behavior seen in tools like Grafana, Jira, or Windows Metro.

  • Draggable & Resizable: It provides the interaction layer out-of-the-box. You don't need to wire up mouse listeners or calculate delta positions.
  • Responsive Breakpoints: Just like CSS media queries, RGL allows you to define different layouts for different screen widths (e.g., 12 columns on desktop, 1 column on mobile).
  • Auto-Packing: When you move a widget, other widgets move out of the way and float up to fill the empty space (vertical compaction).
  • Serialization-Ready: The entire state of the UI is represented by a simple array of objects ({i, x, y, w, h}), making it trivial to save user preferences to a database.
  • Pluggable Widgets: It doesn't care what is inside the grid items; it just manages their bounding boxes.

Code Snippet

The Responsive grid coupled with WidthProvider is the most common usage pattern, allowing the grid to automatically resize when the window changes.

import { Responsive, WidthProvider } from "react-grid-layout";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";

// 1. Enhance the component to automatically listen to window resize events
const ResponsiveGridLayout = WidthProvider(Responsive);

const layout = [
  { i: "stats", x: 0, y: 0, w: 4, h: 2 },
  { i: "chart", x: 4, y: 0, w: 8, h: 4 },
  { i: "feed", x: 0, y: 2, w: 4, h: 2 },
];

export const Dashboard = () => {
  return (
    <ResponsiveGridLayout
      className="layout"
      // 2. Define layouts for different breakpoints
      layouts={{ lg: layout }}
      // 3. Configure grid behavior
      breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
      cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
      rowHeight={30}
      draggableHandle=".drag-handle"
    >
      <div key="stats" className="bg-white border p-4">
        <span className="drag-handle cursor-move">::</span> Stats Widget
      </div>
      <div key="chart" className="bg-white border p-4">
        <span className="drag-handle cursor-move">::</span> Chart Widget
      </div>
      <div key="feed" className="bg-white border p-4">
        <span className="drag-handle cursor-move">::</span> Activity Feed
      </div>
    </ResponsiveGridLayout>
  );
};

In this example, WidthProvider measures the container width and passes it to ResponsiveGridLayout, which then calculates which breakpoint is active (lg, md, etc.) and renders the appropriate column count.

Pros and Cons

No library is perfect; understanding the trade-offs is key to selecting the right tool.

Pros

  • Mature & Battle-Tested: It has been the industry standard for React dashboards for years and powers many enterprise tools.
  • Deterministic Layout: Because it uses absolute positioning, items land exactly where calculations say they should, avoiding the "jumping" issues common in CSS-based drag-and-drop.
  • Feature Complete: Includes collision handling, minimum/maximum item constraints, static (non-movable) items, and right-to-left (RTL) support.

Cons

  • Dynamic Height Difficulty: RGL expects items to have heights in "grid units" (rows). If your content size is dynamic (e.g., an expanding accordion), you have to manually recalculate the item's grid height, which is painful.
  • Performance Heavy: With hundreds of items, the continuous recalculation of layout geometry during a drag can cause frame drops on lower-end devices.
  • Absolute Positioning: The generated DOM uses position: absolute and explicit transform: translate(...). This makes it hard to integrate with normal CSS flow layouts or standard responsive design techniques.

Comparison with Other Layout Solutions

The table below outlines the positioning differences between React Grid Layout and alternatives:

LibraryDesign PhilosophyBest ForPain Points
React Grid LayoutDashboard Engine
JavaScript-controlled absolute positioning.
Admin Dashboards
Apps allowing users to customize their workspace view.
Dynamic Content
Handling widgets that change height based on content is difficult.
CSS GridNative Layout
Browser-native 2D layout system.
Static Layouts
Standard responsive web pages.
No DnD
Dragging and sorting requires writing complex JS from scratch.
dnd-kitHeadless Primitives
Modern, accessible drag-and-drop hooks.
Lists & Kanban
Sortable lists or Kanban boards.
No Grid Logic
You must implement the 2D collision and packing math yourself.

Verdict: When to Adopt

Choose React Grid Layout if your primary requirement is a user-customizable dashboard where widgets can be moved and resized on a 2D plane. It is a specialized tool for that specific interaction pattern. If you just need a responsive grid for displaying content that doesn't move, stick to native CSS Grid.