react-resizable: the drag handle half of react-grid-layout
A simple React component that is resizable with a handle.
At a glance
- What is it?
- A small React component that adds resize handles to any element, with a stateless low level component and a stateful convenience wrapper. As of 4.0 it is TypeScript only, and Flow support is gone.
- Who is it for?
- react-resizable is a good fit when you want drag handles on a panel and nothing more, especially if you already depend on react-draggable, and a poor fit if you need grid snapping, collision handling or layout persistence, because react-grid-layout builds on this rather than the other way round. GitHub reports the last push on 2026-08-05 and v3.1.0 published 2025-12-31, with 4.0 documented as shipping in May 2026.
- 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 66 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 10, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One package, two components, a shared prop list
The README splits the API into exactly two exports. `<Resizable>` is described as a raw component that does not have state, to be used as a building block for larger components by listening to its callbacks and setting its props. `<ResizableBox>` is described as a simple div that manages basic state, convenient for simple use cases.
The stateless one is the interesting design, and it is the reason this package composes. It renders children, attaches handles, and calls `onResize`, `onResizeStart` and `onResizeStop` with the new size. It does not hold the size. Whoever owns the layout decides what to do with the number, which means the component never fights your state management and can sit inside a form, a grid, or a store without a wrapper.
The stateful wrapper exists for the common case where nobody else needs the size. `ResizableBox` is that case in a few lines:
import { ResizableBox } from 'react-resizable';
import 'react-resizable/css/styles.css';
class Example extends React.Component {
render() {
return (
<ResizableBox
width={200}
height={200}
draggableOpts={{grid: [25, 25]}}
minConstraints={[100, 100]}
maxConstraints={[300, 300]}
>
<span>Contents</span>
</ResizableBox>
);
}
}`draggableOpts` here snaps to a 25 by 25 grid and sets bounds of 100 and 300. Both features come from forwarding props to react-draggable's `DraggableCore`, which the prop list documents explicitly.
Installing the styles is not optional
The README is unusually direct about this. It says you must include the associated styles in your application, otherwise the resize handles will not be visible and will not work properly.
import 'react-resizable/css/styles.css';The alternative is a CSS import, `@import 'react-resizable/css/styles.css';`, and the README covers the case where your bundler does not support CSS imports at all: find the styles at `node_modules/react-resizable/css/styles.css` and include them manually.
Installation itself is one command:
npm install --save react-resizableThe `css/` directory at the repository root is why the file is part of the published package, and `package.json` confirms the shipped file list is exactly `build/`, `css/` and `index.js`, with `main` pointing at `index.js` and `types` at `./build/index.d.ts`.
A stylesheet dependency is a real cost in a design system context. If your build pipeline forbids global CSS imports, you will be copying that file into your own styles and keeping it in sync by hand. The README does not document a CSS-in-JS or CSS-modules path.
Version 4.0 dropped Flow and shipped its own types
This is the change an upgrading project has to notice first. The README says that as of 4.0.0 the library is authored in TypeScript and ships bundled type declarations in `build/*.d.ts`, and that you do not need to install `@types/react-resizable`; if you previously installed it, remove it so the bundled types take precedence.
npm uninstall @types/react-resizableThe Flow story is the more consequential removal. The README states Flow is no longer supported as of 4.0.0, and that earlier versions shipped `*.js.flow` sidecar files generated from Flow-annotated source, which have been removed. For a Flow codebase that needs the types, the README's advice is to vendor the last Flow-annotated source locally from the 3.2.0 tag, and it says plainly that those files will not be updated to reflect changes landing after 4.0.0. The official recommendation is to migrate to TypeScript.
The compatibility table makes the version boundaries precise. Version 4.x needs React 16.3 or newer and ships TypeScript; 3.x needs React 16.3 or newer and shipped Flow; 2.x was skipped; 1.x supported React 14 through 17 with Flow types.
The public types are re-exported from the package root, which is a small but useful detail:
import {
Resizable,
ResizableBox,
type ResizeCallbackData,
type ResizeHandleAxis,
type Axis,
type Props as ResizableProps,
} from 'react-resizable';Note the `type` modifiers in the import list. That is TypeScript 5 syntax, and it is the sort of detail that will matter if your `tsconfig` targets an older compiler.
The props that decide how a resize behaves
The README's prop block is the real documentation. `handle` takes either a React element or a function that receives the handle axis and a ref and returns an element, which is how you customise what the grab area looks like. `handleSize` defaults to `[20, 20]` and carries a comment in the type that says if you change it, update your CSS. That comment is the honest admission that the handle styling is coupled to a fixed pixel size.
The behaviour props are the usual set with sensible defaults: `lockAspectRatio` false, `axis` set to `'both'` with `'x'`, `'y'` and `'none'` as the other options, `minConstraints` defaulting to `[20, 20]`, and `maxConstraints` defaulting to `[Infinity, Infinity]`. `resizeHandles` defaults to `['se']`, so a bare component gives you one handle in the south east corner and nothing else.
`ResizeHandleAxis` is a union of the eight compass points, `'s' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne'`, which is what you pass to `resizeHandles` to add corners and edges. The callback signature is `ResizeCallbackData` carrying the node, the size as width and height, and the handle that produced the change, so a single `onResize` handler can behave differently per corner.
One prop deserves its own paragraph because it causes real bugs. `transformScale` defaults to 1, and the README says that if `transform: scale(n)` is set on the parent, this should be set to `n`. Get it wrong and the handles are offset from where the cursor is, which looks like the component being broken rather than a scale mismatch. Unknown props not in the list are passed through to the child, which is how the `style` prop reaches the div `ResizableBox` renders.
What this package does not do
The README does not describe grid layout, collision detection, persistence or any of the things people often mean when they say a resizable layout. There is no positioning system, no ordering when elements overlap, no bounds checking against neighbours, and no serialisation format.
That is not a gap in the documentation, it is the scope. The package description is a simple React component that is resizable with a handle, and the repository tree is consistent with that: `lib/` for the components, `__tests__/` for the tests, `css/` for the stylesheet, `examples/` for the demo, and `build.sh` plus `webpack.config.js` for the build.
Grid behaviour arrives when you add react-draggable, because `draggableOpts` forwards to its `DraggableCore`, and grid snapping in particular is a react-draggable feature that this package passes through. Anything beyond that, meaning layouts that pack and reflow, belongs to react-grid-layout, which is the sibling project by the same organisation and consumes this one.
Custom handles are documented as a supported use rather than an undocumented one, with a section in the table of contents for them and a handle prop that accepts your own element or a render function. That is the extension point worth knowing about if the default 20 pixel grab area does not suit a touch interface.
Maintenance signals, and the one thing to check first
GitHub reports the repository as TypeScript, MIT licensed, not archived, last pushed 2026-08-05, on the `master` branch, with the homepage pointing at a live examples page. The release list reads oddly: v3.1.0, v3.0.5 and v3.0.4 all published 2025-12-31 within a second of each other. That is what a backfill looks like, where old tags were pushed or their timestamps rewritten in one batch, so do not read the publication dates as a release cadence.
The 4.0 entry point is in the compatibility table instead, dated May 12 2026 in the link to the changelog section. So the sequence to verify is: 3.x with Flow types, then 4.x with bundled TypeScript declarations and no Flow sidecars. Anyone upgrading from 1.x or 2.x skips a major version that was never published, which is worth knowing before you diff the changelog.
`package.json` gives the rest of the picture. The scripts are `lint`, `typecheck` running `tsc --noEmit`, `test` running `jest --coverage`, `build` calling `bash build.sh`, and a `preversion` script that chains lint, typecheck and test before a version is cut. The dev dependencies are React 19 types, testing-library, jest 30 and the Babel toolchain with the TypeScript preset, so the test suite runs against current React.
The repository also carries a `CLAUDE.md` at the root, which usually means contributor conventions are written down for automated tooling. That is a sign of an active project rather than a maintained fossil, and it is the reason the first thing to check before pinning is the changelog for 4.0 rather than the tag dates.
Editorial conclusion
react-resizable is a good fit when you want drag handles on a panel and nothing more, especially if you already depend on react-draggable, and a poor fit if you need grid snapping, collision handling or layout persistence, because react-grid-layout builds on this rather than the other way round. GitHub reports the last push on 2026-08-05 and v3.1.0 published 2025-12-31, with 4.0 documented as shipping in May 2026. Install 4.0 only if your project is already on TypeScript, because the bundled Flow types are gone.
Frequently asked questions
How do I install react-resizable and make the handles work?
Run `npm install --save react-resizable` and then import the stylesheet, with `import 'react-resizable/css/styles.css';` in your entry point or `@import 'react-resizable/css/styles.css';` in your CSS. The README states the styles are required, since without them the resize handles are not visible and do not work properly. `package.json` ships `build/`, `css/` and `index.js`.
Do I still need @types/react-resizable?
No. As of 4.0.0 the library ships its own declarations in `build/*.d.ts`, so the README says to remove `@types/react-resizable` if you had installed it, so the bundled types take precedence. Flow is no longer supported in 4.x, and the README's advice for Flow users is to vendor the last Flow-annotated source from the 3.2.0 tag, which will not track later changes.
How do I resize from more than one corner, or keep an aspect ratio?
`resizeHandles` takes an array of `ResizeHandleAxis` values, which are the eight compass points `'s'`, `'w'`, `'e'`, `'n'`, `'sw'`, `'nw'`, `'se'`, `'ne'`, and it defaults to `['se']` alone. `lockAspectRatio` defaults to false. Bounds come from `minConstraints` and `maxConstraints`, and `draggableOpts` forwards to react-draggable's `DraggableCore` if you want grid snapping.
Official sources
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.
[](https://hysenlabs.com/projects/react-grid-layout-react-resizable)