Open-source project
bokuweb/react-rnd avatar
bokuweb/react-rnd

react-rnd: a resizable and draggable React component

đź–± A resizable and draggable component for React.

4,325 stars330 forksTypeScriptMIT

At a glance

What is it?
react-rnd wraps a single React element in drag and resize behaviour, controlled or uncontrolled. It is a good fit for panels, dialogs and canvas items, and the wrong fit for sortable lists.
Who is it for?
Adopt react-rnd when you need one element the user can move and resize, with size and position you can control from state, and you are willing to wire drag bounds and scale yourself. Do not adopt it for sortable lists or tree reordering, where a dedicated drag and drop library with drop targets is the better tool.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 146 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem react-rnd solves: free positioning inside a React tree

Most React UI is laid out by the browser. Flexbox and grid decide where things go, and the user never moves them. react-rnd is for the cases where that is not true: a floating panel the user drags around, a dialog they resize, a video box with a locked aspect ratio, an item on a canvas. The README describes it plainly as "A resizable and draggable component for React", and that is the whole scope. It is not a drag and drop system with drop targets and sortable collections. It takes one child and makes that child movable and resizable, then reports the result back through callbacks. The audience is React developers building editor-like or dashboard-like interfaces, not developers building kanban boards. The distinction matters, because the README documents no drop target, no sortable list and no reordering API. If that is what you need, this is the wrong package, and the related searches for react-rnd versus dnd-kit point at exactly that confusion.

Controlled and uncontrolled: how size and position actually flow

react-rnd offers two modes and the README separates them by prop name. In the uncontrolled mode you pass default with x, y, width and height, and the component keeps its own internal state. In the controlled mode you pass size and position, and the README says to use them "if you need to control size state by yourself". The data flow then runs through the stop callbacks. onDragStop receives the event and a delta object with x and y, and the README's example writes those back into component state. onResizeStop receives the event, a direction, a ref, a delta and a position, and the example reads ref.style.width and ref.style.height and spreads the position. Note the asymmetry: the drag callback hands you numbers, the resize callback hands you a DOM ref and expects you to read the style off it. That is a small design wart, and it means controlled resizing depends on the rendered element rather than on a plain value. The README also shows an onResize variant that reads ref.offsetWidth and ref.offsetHeight instead, which gives you integer pixels rather than the style string. Both are in the documentation; neither is explained in terms of when to prefer one.

Constraints the component enforces: grids, bounds, aspect ratio and scale

The props list is where react-rnd earns its keep. minWidth, minHeight, maxWidth and maxHeight accept a number, a pixel string or a percentage, and the README gives 300, '300px' and 50% as valid forms for each. resizeGrid and dragGrid take a two-number tuple and set the increments that resizing and moving snap to, defaulting to [1, 1]. lockAspectRatio takes true to lock the ratio from the initial size, or a number to pin a specific ratio; the README warns that with a numeric value you must set the initial width and height to values with the correct ratio. lockAspectRatioExtraWidth and lockAspectRatioExtraHeight exist for the case where the locked box has chrome around it, and the README's own example is a 16:9 video with a 50px side bar or a 50px header bar. scale is the one to reach for when the element sits inside a transformed parent: the README says it lets you get correct drag and resize deltas while zoomed in or out via a transform or matrix. These are the props that separate react-rnd from writing pointer handlers yourself, and they are also the ones most likely to need tuning against a real layout.

Install and a first controlled example

The README gives two install commands, one for npm and one for yarn. Either produces the same dependency in your project. The current published version in package.json is 10.5.3.

bash
npm i -S react-rnd

The README's first usage example is the uncontrolled form: pass default with x, y, width and height, and the component manages its own state. Nothing else is required, and the child text renders inside the box.

javascript
<Rnd
  default={{
    x: 0,
    y: 0,
    width: 320,
    height: 200,
  }}
>
  Rnd
</Rnd>

For a real application you will usually want the controlled form, so the size and position live in your own state and can be persisted or synced. The README's second example passes size and position from state and writes them back in onDragStop and onResizeStop. After a drag or a resize ends, the box stays where you left it because your state now holds the new values.

javascript
<Rnd
  size={{ width: this.state.width,  height: this.state.height }}
  position={{ x: this.state.x, y: this.state.y }}
  onDragStop={(e, d) => { this.setState({ x: d.x, y: d.y }) }}
  onResizeStop={(e, direction, ref, delta, position) => {
    this.setState({
      width: ref.style.width,
      height: ref.style.height,
      ...position,
    });
  }}
>
  001
</Rnd>

The README also lists an instance API with two methods, updateSize(size) and updatePosition({ x, y }), for pushing new values into the component from outside React state. The README does not show a worked example of either call, so treat the signatures as the contract and verify the behaviour against the Storybook before relying on them.

Where react-rnd stops: no drop targets, no ordering, no rotation

The honest limitation is scope. react-rnd moves and resizes one element. It has no concept of a drop zone, so it cannot tell you that a dragged panel landed over a column, and it has no ordering model, so it cannot reorder a list. Building a sortable board on top of it means writing collision detection and index math yourself, which is more work than picking a library that ships those primitives. The related searches include react rnd rotate, and the README documents no rotation prop or transform handling beyond the scale prop for transformed parents, so rotation is not part of the documented surface. There is a second, subtler limitation in the controlled mode: because onResizeStop asks you to read width and height off a DOM ref, the values you store are strings from the element style, not plain numbers. If you persist those values and later feed them back through size, you are round-tripping CSS strings, which is workable but easy to get subtly wrong with percentages. The README does not document rollback, undo, or any conflict resolution when two sources of truth disagree about position, so if your application mutates position from both the component and a server, you own the reconciliation.

Alternatives and the actual difference in approach

The related searches put react-rnd next to React-draggable, React-moveable, react-dnd and dnd-kit, and the split is real. React-draggable, which react-rnd builds on conceptually, handles dragging only; if you need resize too, you would add a separate resizer and wire the two together, which is roughly the work react-rnd has already done for you. React-moveable takes the opposite approach: it wraps a target element and provides a moveable controller with handles, which suits canvas and editor scenarios where many elements are manipulated through a shared controller rather than each element owning its own drag state. react-dnd and dnd-kit are drag and drop systems built around sources and targets, with the drop logic as the centre of the API. That is the right shape for sortable lists and trees, and the wrong shape for a single floating panel, because you would be configuring a drag source and a drop target to move something that has nowhere to drop. Pick react-rnd when the element's final position is the point. Pick a source-and-target library when the element's destination is the point.

Maintenance, licence and what upgrading costs

The repository is not archived, and the last push was on 2026-05-12. The release history is uneven: 10.5.3 on 2026-03-10, v10.4.13 on 2024-09-21, and v10.4.1 on 2022-12-19. Two long gaps sit between those tags, so the cadence is bursty rather than steady, and a consumer should plan for that. The project is MIT licensed, which permits commercial use and modification; the LICENSE file is at the repository root. The build is Rollup-based, with separate production bundles for the main and ES5 outputs, and the package ships types at ./lib/index.d.ts plus a Flow definition copied from src/index.js.flow. That means TypeScript consumers get types from the published package, and Flow consumers get a hand-maintained definition that is copied rather than generated, so it can drift from the implementation. The package declares main, module and jsnext:main, so bundlers will pick the ES module build. The repository uses pnpm-lock.yaml and a Renovate config, which suggests dependency updates are automated, but the README does not describe a release process or a support window. There is a Storybook at bokuweb.github.io/react-rnd/stories and a set of CodeSandbox examples, including one with hooks and one with TypeScript, which are the fastest way to check current behaviour without reading the source.

Editorial conclusion

Adopt react-rnd when you need one element the user can move and resize, with size and position you can control from state, and you are willing to wire drag bounds and scale yourself. Do not adopt it for sortable lists or tree reordering, where a dedicated drag and drop library with drop targets is the better tool. Before committing, verify in a browser how dragHandleClassName and lockAspectRatio behave with your layout, and check whether the props you need are documented in the README or only visible in the Storybook stories.

Frequently asked questions

What is react-rnd?

It is a React component that makes a single child element draggable and resizable. The README describes it as "A resizable and draggable component for React" and documents props for minimum and maximum size, snapping grids, aspect ratio locking and canvas scale.

How is react-rnd different from react-dnd?

react-rnd moves and resizes one element and reports its new size and position through callbacks such as onDragStop and onResizeStop. react-dnd is built around drag sources and drop targets, so it is aimed at moving items between containers rather than positioning a single floating element.

How do I install react-rnd?

The README gives npm i -S react-rnd for npm and yarn add react-rnd for yarn. The published version in package.json is 10.5.3.

How do I control the size and position of a react-rnd element from my own state?

Pass the size and position props instead of default, and write the new values back in onDragStop and onResizeStop. The README's example reads ref.style.width and ref.style.height in onResizeStop and spreads the position object into state.

Does react-rnd support rotation?

The README documents no rotation prop. Its scale prop is for elements inside a transformed or zoomed parent, so the drag and resize deltas come out correct, not for rotating the element itself.

Official sources

  1. bokuweb/react-rnd on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bokuweb-react-rnd.svg)](https://hysenlabs.com/projects/bokuweb-react-rnd)