# gridstack.js: the layout engine under your draggable dashboard

> A dependency-free TypeScript library that turns ordinary HTML into a drag and resize grid, shipped with React, Angular and Vue wrappers and a long list of breaking majors.

**gridstack/gridstack.js** — Build interactive dashboards in minutes.

- Repository: https://github.com/gridstack/gridstack.js
- Website: https://gridstackjs.com
- Stars: 9,191 · Forks: 1,418
- Language: TypeScript
- License: MIT
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/gridstack-gridstack-js

## A grid of positioned DOM nodes rather than a drawn canvas

gridstack.js is a layout engine, not a charting library. It takes a container element, turns its children into cells, and keeps each cell's x, y, width and height in sync with what a user does by dragging or resizing it. The repository describes itself as a mobile-friendly modern pure TypeScript library for dashboard layout and creation with no external dependencies, and that last part is literal rather than marketing: lodash was removed in v0.5, the jQuery API in v1, and v3 was a complete HTML5 rewrite.

The mechanism matters more than the tagline. Layout is done with CSS column based percentages rather than absolute pixel positions, which is why the README insists on including gridstack.min.css next to the script. The library writes classes and CSS custom properties onto the item elements and reads geometry back from the browser, so your widget content stays ordinary HTML inside a cell. That is a different bargain from a canvas dashboard, where your content becomes a list of draw calls, and it is why a gridstack cell can hold a table, an iframe or a live chart without special treatment.

The project states its lineage plainly, describing itself as inspired by the no longer maintained gridster. The distance between the two is mostly about event handling and mobile input: v6 moved to native mouse and touch events and dropped the jQuery UI version that older forks still depend on.

## Installing the package and including the stylesheet

A grid without its CSS is a stack of divs, so the README treats installation as two steps.

```bash
yarn add gridstack
// or
npm install --save gridstack
```

For an ES6 or TypeScript project, the stylesheet is imported beside the module rather than linked in HTML:

```js
import 'gridstack/dist/gridstack.min.css';
import { GridStack } from 'gridstack';
```

For a plain page, the README points at the combined bundle, and the -all.js suffix matters because the single file exports several module formats side by side:

```html
<link href="node_modules/gridstack/dist/gridstack.min.css" rel="stylesheet"/>
<script src="node_modules/gridstack/dist/gridstack-all.js"></script>
```

There is a documented escape hatch for old browsers. The README offers an es5 build plus a polyfill, and it is unusually candid about browser support history: Internet Explorer was dropped in v2, restored in v4.4 by an external contributor, and dropped again in v12 because a CSS variable was needed. The author's stated position is that they have no interest in testing obsolete browsers, so the es5 path may break again without much warning.

## Filling a grid dynamically, from data, or from markup

There are three ways to put content on the grid, and the choice is mostly about who owns the layout state.

The dynamic route calls init on the container and then adds widgets by object:

```js
var grid = GridStack.init();
grid.addWidget({w: 2, content: 'item 1'});
```

The serialized route is the one you want for a saved dashboard, because the array is the layout and can be round-tripped to your own storage:

```js
const serializedData = [
  {x: 0, y: 0, w: 2, h: 2},
  {x: 2, y: 3, w: 3, content: 'item 2'},
  {x: 1, y: 3}
];

grid.load(serializedData);
```

The third route writes the markup first and initialises afterwards, which suits server-rendered pages. Cell attributes go straight on the element:

```html
<div class="grid-stack">
  <div class="grid-stack-item">
    <div class="grid-stack-item-content">Item 1</div>
  </div>
  <div class="grid-stack-item" gs-w="2">
    <div class="grid-stack-item-content">Item 2 wider</div>
  </div>
</div>
```

Note what the library does not do in any of the three cases. It does not fetch your data, render your widgets or persist the result. Reading the array back out and storing it is your code, which is the honest division of labour here.

## What v14 changed and why the major number keeps moving

v14.0.0 was published on 2026-09-21, the same calendar day as the repository's most recent push, and its notes call out two large changes. The old `float` boolean is replaced by a `mode` setting that accepts top, float, list or compact, where list mode re-flows items in sequential order like a sortable list instead of pushing everything else down. The second change adds a `cellHeight: 'fill'` option so rows divide the whole container height rather than taking a fixed cell size.

That pattern is not a one-off. The README carries a migration section for every major version from v0.6 through v14, and the recent releases show the same churn in smaller form: v13.2.0 removed `printMode` and added `PrintOptions.mode` in the same release, v13.3.0 added `PrintOptions.breakInside` and a print-avoid-break class, and v12 is where Internet Explorer support ended. Reading a major version here is not ceremony, because option names you saved against a year ago may be gone.

The upside of a project this willing to break its own API is that the alternative, gridster, is simply not maintained. Neither choice is free.

## React, Angular and Vue wrappers kept in the same tree

The repository tree shows the shape of the effort: src/ for the core engine, then angular/, react/ and vue/ directories with their own build steps, doc/ for the generated API, demo/ for roughly two dozen example pages, and both e2e/ and spec/ for tests. The build script in package.json chains the core build through the three framework builds and then regenerates the documentation, which tells you the wrappers are first-class rather than community afterthoughts.

The wrappers are not the only integrations listed. For Ember the README points at ember-gridstack, for AngularJS at gridstack-angular, and for knockout it points at a demo using a component. What is refreshing is the honesty about one of them: the Angular 9 entry is described as a very old v0.3 instance, recommended for concept only if you want a directive instead of a component, and explicitly not vetted by the maintainer.

The demo directory is worth browsing before writing any code. Files named list.html, nested.html, nested_constraint.html, locked.html, mobile.html, print.html, custom-engine.html and cell-height.html map almost one to one onto the features the release notes keep changing.

## Where gridstack stops and plain CSS grid takes over

Native CSS grid is the honest alternative, and it wins in one specific case: when the layout is responsive by breakpoint and nobody needs to drag anything. CSS grid gives you reflow, auto-placement and responsive tracks with no JavaScript at all. What it cannot give you is a user picking a cell size and having that choice persist.

gridstack's own boundary is easier to state. It draws no charts, binds no data, and stores nothing. Every dashboard built on it needs a second system for what goes inside the cells and a third for where the serialized layout is kept, and the library's value is entirely in the third dimension, which is user editing. A monitoring view that is the same for every user is a case where plain CSS grid or a flex layout is less work.

The testing setup is a fair signal of how seriously the geometry work is taken. The tree carries vitest.config.ts, vitest.setup.ts, playwright.config.ts, a protractor config still in place from the older era, and a TESTING.md at the root, with e2e/ holding browser-level cases. The README also states that the markdown API documentation is regenerated with the code, which means it covers unreleased changes as well as the published version, a small but real advantage when you are reading the docs and the code side by side.

## Conclusion

gridstack.js earns its place when the dashboard layout has to be user-editable and saved, because that is the part CSS grid cannot do for you. The costs are real and worth naming: it is a layout engine with no widgets and no persistence, you own saving the serialized layout, and every major version has carried breaking changes, with v14 replacing the float option with a mode setting. Start with grid.load() on a static array and the doc/API.md file, which the README says is regenerated with the code, then read the migration notes for your target version before shipping a layout that users have already saved.

## FAQ

### Does gridstack.js depend on jQuery?

No. The README records that the jQuery API was removed in v1 and that v3 was a complete HTML5 rewrite, with v6 moving to native mouse and touch events and dropping the jQuery UI version. Older forks in the wild still assume jQuery, so check which version you are installing before copying a snippet from an old tutorial.

### How do I save and restore a gridstack layout?

Read the layout back out as an array of cell objects and store it wherever your own app keeps state, then hand the same array to load() on the next visit. The README demonstrates loading a serialized array with x, y, w and h values, which is the shape you persist. The library stores nothing itself.

### Is there an official React or Vue wrapper for gridstack?

Yes, and they live in the same repository under react/ and vue/, with build:react and build:vue scripts in package.json alongside an angular/ directory. The README also lists third-party wrappers for Ember, AngularJS and knockout, but warns that the Angular 9 option is an old v0.3 instance it has not vetted.

## Sources

- [gridstack/gridstack.js on GitHub](https://github.com/gridstack/gridstack.js)
- [License: MIT](https://github.com/gridstack/gridstack.js/blob/master/LICENSE)
- [Project website](https://gridstackjs.com)
- [README](https://github.com/gridstack/gridstack.js/blob/master/README.md)
- [Releases](https://github.com/gridstack/gridstack.js/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/gridstack-gridstack-js
