NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #1327 most downloaded on npm
<img src="https://react-resizable-panels.vercel.app/og.png" alt="react-resizable-panels logo" width="400" height="210" />
Last release 11 days ago
06 Sep 2026
Ships fairly regularly
a new release about every 2 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
5 versions withdrawn
withdrawn after publishing
4 years old
206 releases · first in 2022
555: Allow resizable panels to be rendered into a different Window (e.g. popup or frame) by accessing globals through element.ownerDocument.defaultVie
element.ownerDocument.defaultViewuseDefaultLayout: Deprecated groupId param in favor of id to avoid confusion; (there is no actual requirement for the Group to have a matching id)
useDefaultLayout: Deprecated groupId param in favor of id to avoid confusion; (there is no actual requirement for the Group to have a matching id)One column per quarter.
552: useDefaultLayout now debounces calls to storage.setItem by 150ms
useDefaultLayout now debounces calls to storage.setItem by 150msuseDefaultLayout now debounces calls to storage.setItem by 150ms// To opt out of this change
useDefaultLayout({
debounceSaveMs: 0,
groupId: "test-group-id",
storage: localStorage,
})
[!NOTE] Some may consider this a breaking change, considering the default value is 150ms rather than 0ms. I think in practice this should only impact unit tests which can be easily fixed by overriding the default (as shown above) or by using fake timers.
Changes like this are often judgement calls, but I think on balance it's better to correct my initial oversight of not debouncing this by default.
8604491: Fix edge case bug with panel constraints not being properly invalidated after resize
- #551: Expand fixed-size element support
- #542: Clicks on higher z-index elements (e.g. modals) should not trigger separators behind them - #547: Don't re-mount Group when defaultLayout or d
z-index elements (e.g. modals) should not trigger separators behind themdefaultLayout or disableCursor props changePanel id changesNothing published for this version
40d4356: Gracefully handle invalid defaultLayout value
Nothing published for this version
Nothing published for this version
Nothing published for this version
f07bf00: Reset pointer-event styles after "pointerup" event
pointer-event styles after "pointerup" event0796644: Account for Flex gap when calculating pointer-move delta %
- #535: Updated docs to make size and layout formats clearer
e08fe42: Improve iOS/Safari resize UX
Fixed TS type for defaultLayout value returned from useDefaultLayout
defaultLayout value returned from useDefaultLayoutExport GroupImperativeHandle and PanelImperativeHandle types.
GroupImperativeHandle and PanelImperativeHandle types.## 4.0.1 - #530: Edge case bug fix: Account for pointer resize events near edge of window/iframe
Version 4 of react-resizable-panels offers more flexible size constraints– supporting units as pixels, percentages, REMs/EMs, and more. Support for server-rendering (including Server Components) has also been expanded.
Version 4 of react-resizable-panels offers more flexible size constraints– supporting units as pixels, percentages, REMs/EMs, and more. Support for se
Version 4 of react-resizable-panels offers more flexible size constraints– supporting units as pixels, percentages, REMs/EMs, and more. Support for server-rendering (including Server Components) has also been expanded.
Refer to the docs for a complete list of props and API methods. Below are some examples of migrating from version 3 to 4, but first a couple of potential questions:
<dl> <dt>Q: Why'd you rename <component> or <prop>?</dt> <dd>A: The most likely reason is that I think the new name more closely aligns with web standards like WAI-ARIA and CSS. For example, the <code>PanelResizeHandle</code> component was renamed to <code>Separator</code> to better align with the <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/separator_role">ARIA "separator" role</a> and the <code>direction</code> prop was renamed to <code>orientation</code> to better align with the <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-orientation">ARIA <code>orientation</code> attribute </a>.</dd> <dt>Q: Why'd you remove support for <feature>?</dt> <dd>A: Probably because it wasn't used widely enough to justify the complexity required to maintain it. If it turns out that I'm mistaken, features can always be (re)added but it's more difficult to remove them.</dd> <dt>Q: Were the <code>onCollapse</code> and <code>onExpand</code> event handlers removed?</dt> <dd>A: Yes. Use the <code>onResize</code> event handler instead:
onResize={(size) => {
// Either this
const isCollapsed = size === collapsedSize;
// Or this:
panelRef.isCollapsed();
}}
</dd> </dl>
// Version 3
import { PanelGroup, Panel, PanelResizeHandle } from "react-resizable-panels";
<PanelGroup direction="horizontal">
<Panel defaultSize={30} minSize={20}>left</Panel>
<PanelResizeHandle />
<Panel defaultSize={30} minSize={20}>right</Panel>
</PanelGroup>
// Version 4
import { Group, Panel, Separator } from "react-resizable-panels";
<Group orientation="horizontal">
<Panel defaultSize={30} minSize={20}>left</Panel>
<Separator />
<Panel defaultSize={30} minSize={20}>right</Panel>
</Group>
// Version 3
import { PanelGroup, Panel, PanelResizeHandle } from "react-resizable-panels";
<PanelGroup autoSaveId="unique-group-id" direction="horizontal">
<Panel>left</Panel>
<PanelResizeHandle />
<Panel>right</Panel>
</PanelGroup>
// Version 4
import { Group, Panel, Separator, useDefaultLayout } from "react-resizable-panels";
const { defaultLayout, onLayoutChange } = useDefaultLayout({
groupId: "unique-group-id",
storage: localStorage
});
<Group defaultLayout={defaultLayout} onLayoutChange={onLayoutChange}>
<Panel>left</Panel>
<Separator />
<Panel>right</Panel>
</Group>
[!NOTE] Refer to the docs for examples of persistent layouts with server rendering and server components.
// Version 3
import { PanelGroup, Panel, PanelResizeHandle } from "react-resizable-panels";
<PanelGroup autoSaveId="unique-group-id" direction="horizontal">
{showLeftPanel && (
<>
<Panel id="left" order={1}>left</Panel>
<PanelResizeHandle />
</>
)}
<Panel id="center" order={2}>center</Panel>
{showRightPanel && (
<>
<PanelResizeHandle />
<Panel id="right" order={3}>right</Panel>
</>
)}
</PanelGroup>
// Version 4
import { Group, Panel, Separator } from "react-resizable-panels";
<Group>
{showLeftPanel && (
<>
<Panel id="left">left</Panel>
<Separator />
</>
)}
<Panel id="center">center</Panel>
{showRightPanel && (
<>
<Separator />
<Panel id="right">right</Panel>
</>
)}
</Group>
// Version 3
import { PanelGroup, Panel, PanelResizeHandle } from "react-resizable-panels";
import type { ImperativePanelGroupHandle, ImperativePanelHandle }from "react-resizable-panels";
const panelRef = useRef<ImperativePanelHandle>(null);
const panelGroupRef = useRef<ImperativePanelGroupHandle>(null);
<PanelGroup direction="horizontal" ref={panelGroupRef}>
<Panel ref={panelRef}>left</Panel>
<PanelResizeHandle />
<Panel>right</Panel>
</PanelGroup>
// Version 4
import { Group, Panel, Separator, useGroupRef, usePanelRef } from "react-resizable-panels";
const groupRef = useGroupRef();
const panelRef = usePanelRef();
<Group groupRef={groupRef} orientation="horizontal">
<Panel panelRef={panelRef}>left</Panel>
<Separator />
<Panel>right</Panel>
</Group>
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
- #517: Fixed Firefox bug that caused resizing to be interrupted unexpected
Nothing published for this version
- #512: Fixed size precision regression from 2.0.17
- #503: Support custom cursors
- #492: Fix compatibility with Cloudflare workers
Fallback for type of HTMLElement to better support portal edge cases
HTMLElement to better support portal edge cases- #479: Improve support for Cloudflare Workers and Vercel Functions - #480: Fixed package.json#types reference
- #478: Module is ESM-only in order to better work with modern tooling. - #475: "pointerup" and "pointercancel" listeners are now attached to the owne
Nothing published for this version
Nothing published for this version
- #427: Stacking order checks also check for SVGElements (bug fix) - #433: Exclude src directory from NPM package
Removed "engines" block and replaced with "packageManager"
"engines" block and replaced with "packageManager"document.direction for RTL detection; use inherited style instead- Add react v19 to peer deps
Improve TypeScript HTML tag type generics
Edge case bug fix for a resize handle unmounting while being dragged
Suppress invalid layout warning for empty panel groups
Fix cursor icon behavior in nested panels
onDragging regression (#391)Add opt-in support for setting the `"nonce"` attribute for the global cursor style
"nonce" attribute for the global cursor style (#386)Improve obfuscation for React.useId references
React.useId references (#382)Force eager layout re-calculation after panel added/removed
Handle pointer event edge case with different origin iframes
Reset global cursor if an active resize handle is unmounted
onFocus or onBlur props (#370)Add optional minSize override param to panel expand imperative API
minSize override param to panel expand imperative APIInline object hitAreaMargins will not trigger re-initialization logic unless inner values change
hitAreaMargins will not trigger re-initialization logic unless inner values change (#342)Prevent pointer events handled by resize handles from triggering elements behind/underneath
Replaced .toPrecision() with .toFixed() to avoid undesirable layout shift
.toPrecision() with .toFixed() to avoid undesirable layout shift (#323)Better account for high-precision sizes with onCollapse and onExpand callbacks
onCollapse and onExpand callbacks (#325)Better account for high-precision collapsedSize values
collapsedSize values (#325)Fix potential cycle in stacking-order logic for an unmounted node
Improve resize for edge cases with collapsed panels; intermediate resize states should now fall back to the most recent valid layout rather than the i
Fix resize handle cursor hit detection when when viewport is scrolled
Fix conditional layout edge case
Fix case where pointer event listeners were sometimes added to the document unnecessarily
Panel/PanelGroup/PanelResizeHandle` pass "id" prop through to DOM
Panel/PanelGroup/`PanelResizeHandle`` pass "id" prop through to DOM (#299)Panel attributes data-panel-collapsible and data-panel-size are no longer DEV-only (#297)Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →