This guide will help you migrate to react-split-pane v3.0.0. Version 3 is a complete rewrite with modern React patterns, TypeScript support, and improved accessibility.
v3.0.0 introduces several breaking changes from v0.1.x:
- Component structure: Children must be wrapped in
<Pane>components - Props renamed:
split→direction, callback names changed - Props moved: Size constraints moved from
<SplitPane>to<Pane> - Terminology:
vertical/horizontalmeanings swapped to match CSS flex direction - New features: Keyboard navigation, ARIA attributes, touch support, snap points
- Removed:
primaryprop,allowResizeper-pane,Resizerclass names
import SplitPane from 'react-split-pane';
<SplitPane split="vertical" minSize={50} defaultSize={200}>
<div>Left</div>
<div>Right</div>
</SplitPane>import { SplitPane, Pane } from 'react-split-pane';
<SplitPane direction="horizontal">
<Pane minSize={50} defaultSize={200}>
<div>Left</div>
</Pane>
<Pane>
<div>Right</div>
</Pane>
</SplitPane>// v0.1.x
import SplitPane from 'react-split-pane';
// v3
import { SplitPane, Pane } from 'react-split-pane';In v0.1.x, you could use any element as children. In v3, all children must be <Pane> components:
// v0.1.x
<SplitPane split="vertical">
<div>Pane 1</div>
<div>Pane 2</div>
</SplitPane>
// v3
<SplitPane direction="horizontal">
<Pane>
<div>Pane 1</div>
</Pane>
<Pane>
<div>Pane 2</div>
</Pane>
</SplitPane>The meaning of vertical and horizontal has been swapped to align with CSS flexbox terminology:
| v0.1.x | v3 | Layout |
|---|---|---|
split="vertical" |
direction="horizontal" |
Panes side-by-side (left/right) |
split="horizontal" |
direction="vertical" |
Panes stacked (top/bottom) |
In v3, direction describes the flex direction:
horizontal= panes arranged horizontally (side-by-side)vertical= panes arranged vertically (stacked)
// v0.1.x - side-by-side panes
<SplitPane split="vertical">
// v3 - side-by-side panes
<SplitPane direction="horizontal">// v0.1.x - stacked panes
<SplitPane split="horizontal">
// v3 - stacked panes
<SplitPane direction="vertical">Size constraints have moved from <SplitPane> to individual <Pane> components:
// v0.1.x
<SplitPane split="vertical" minSize={50} maxSize={500} defaultSize={200}>
<div>Pane 1</div>
<div>Pane 2</div>
</SplitPane>
// v3
<SplitPane direction="horizontal">
<Pane minSize={50} maxSize={500} defaultSize={200}>
<div>Pane 1</div>
</Pane>
<Pane>
<div>Pane 2</div>
</Pane>
</SplitPane>v3 accepts both numbers (pixels) and strings with units:
// v0.1.x - numbers only (pixels)
<SplitPane minSize={50} defaultSize={200}>
// v3 - numbers or strings with units
<Pane minSize={50} defaultSize={200}> // pixels
<Pane minSize="50px" defaultSize="200px"> // explicit pixels
<Pane minSize="10%" defaultSize="25%"> // percentages| v0.1.x | v3 | Notes |
|---|---|---|
onDragStarted |
onResizeStart |
Now receives ResizeEvent object |
onChange |
onResize |
Receives (sizes[], event) |
onDragFinished |
onResizeEnd |
Receives (sizes[], event) |
// v0.1.x
<SplitPane
onDragStarted={() => console.log('started')}
onChange={(size) => console.log(size)}
onDragFinished={(size) => console.log('finished', size)}
>
// v3
<SplitPane
onResizeStart={(event) => console.log('started', event.source)}
onResize={(sizes, event) => console.log(sizes)}
onResizeEnd={(sizes, event) => console.log('finished', sizes)}
>The ResizeEvent object includes:
sizes: Array of pane sizes in pixelssource:'mouse'|'touch'|'keyboard'originalEvent: The original DOM event
The primary prop has been removed. In v3, sizes are distributed proportionally when the container resizes. For controlled sizing, use the size prop on each <Pane>:
// v0.1.x
<SplitPane split="vertical" defaultSize={200} primary="second">
// v3 - use controlled mode with state
function App() {
const [sizes, setSizes] = useState([null, 200]); // second pane fixed
return (
<SplitPane onResize={setSizes}>
<Pane size={sizes[0]}>Left</Pane>
<Pane size={sizes[1]}>Right (fixed)</Pane>
</SplitPane>
);
}// v0.1.x
<SplitPane allowResize={false}>
// v3
<SplitPane resizable={false}>The step prop now applies to keyboard navigation. Use snapPoints for drag snapping:
// v0.1.x - step for dragging
<SplitPane step={50}>
// v3 - step for keyboard, snapPoints for dragging
<SplitPane
step={10} // keyboard arrow key step
snapPoints={[100, 200, 300, 400]} // drag snap positions
snapTolerance={20} // snap sensitivity
>| v0.1.x | v3 |
|---|---|
SplitPane |
split-pane |
Resizer |
split-pane-divider |
Pane1, Pane2 |
split-pane-pane |
| v0.1.x | v3 |
|---|---|
style |
style |
paneStyle |
Use <Pane style={}> |
pane1Style |
Use <Pane style={}> on first pane |
pane2Style |
Use <Pane style={}> on second pane |
resizerStyle |
dividerStyle |
// v0.1.x
<SplitPane
style={{ height: '100vh' }}
pane1Style={{ background: 'red' }}
pane2Style={{ background: 'blue' }}
resizerStyle={{ width: 10 }}
>
<div>Pane 1</div>
<div>Pane 2</div>
</SplitPane>
// v3
<SplitPane
style={{ height: '100vh' }}
dividerStyle={{ width: 10 }}
>
<Pane style={{ background: 'red' }}>
<div>Pane 1</div>
</Pane>
<Pane style={{ background: 'blue' }}>
<div>Pane 2</div>
</Pane>
</SplitPane>// v0.1.x - CSS class customization
<SplitPane resizerClassName="my-resizer">
// v3 - custom component or className
<SplitPane dividerClassName="my-divider">
// v3 - fully custom divider component
function CustomDivider(props) {
return (
<div {...props} className="my-custom-divider">
<span className="grip-icon" />
</div>
);
}
<SplitPane divider={CustomDivider}>// v0.1.x
<SplitPane
defaultSize={parseInt(localStorage.getItem('splitPos'), 10) || 200}
onChange={(size) => localStorage.setItem('splitPos', size)}
>
<div>Pane 1</div>
<div>Pane 2</div>
</SplitPane>
// v3 - using the usePersistence hook
import { SplitPane, Pane } from 'react-split-pane';
import { usePersistence } from 'react-split-pane/persistence';
function App() {
const [sizes, setSizes] = usePersistence({ key: 'splitPos' });
return (
<SplitPane onResize={setSizes}>
<Pane size={sizes[0] || 200}>Pane 1</Pane>
<Pane>Pane 2</Pane>
</SplitPane>
);
}v3 supports 2+ panes natively (no nesting required):
// v0.1.x - required nesting for 3+ panes
<SplitPane split="vertical">
<div>Pane 1</div>
<SplitPane split="vertical">
<div>Pane 2</div>
<div>Pane 3</div>
</SplitPane>
</SplitPane>
// v3 - native support for multiple panes
<SplitPane direction="horizontal">
<Pane>Pane 1</Pane>
<Pane>Pane 2</Pane>
<Pane>Pane 3</Pane>
</SplitPane>v2.x had a different API than v0.1.x. It already used <Pane> components but with different prop names.
import SplitPane from 'react-split-pane';
import Pane from 'react-split-pane/lib/Pane';
<SplitPane split="vertical" onChange={handleChange}>
<Pane initialSize="200px" minSize="100px" maxSize="500px">
<div>Left</div>
</Pane>
<Pane>
<div>Right</div>
</Pane>
</SplitPane>import { SplitPane, Pane } from 'react-split-pane';
<SplitPane direction="horizontal" onResize={handleChange}>
<Pane defaultSize="200px" minSize="100px" maxSize="500px">
<div>Left</div>
</Pane>
<Pane>
<div>Right</div>
</Pane>
</SplitPane>| v2.x | v3 | Notes |
|---|---|---|
split="vertical" |
direction="horizontal" |
Terminology swapped |
split="horizontal" |
direction="vertical" |
Terminology swapped |
initialSize |
defaultSize |
Prop renamed |
onChange |
onResize |
Callback renamed, signature changed |
onResizeStart |
onResizeStart |
Same name, different signature |
onResizeEnd |
onResizeEnd |
Same name, different signature |
resizerSize |
N/A | Use CSS to style divider width |
// v2.x
import SplitPane from 'react-split-pane';
import Pane from 'react-split-pane/lib/Pane';
// v3
import { SplitPane, Pane } from 'react-split-pane';// v2.x
<SplitPane
onChange={(sizes) => console.log(sizes)}
onResizeStart={() => console.log('started')}
onResizeEnd={(sizes) => console.log('ended', sizes)}
>
// v3
<SplitPane
onResize={(sizes, event) => console.log(sizes, event.source)}
onResizeStart={(event) => console.log('started', event.source)}
onResizeEnd={(sizes, event) => console.log('ended', sizes)}
>Dividers are now keyboard accessible:
- Arrow Keys: Resize by step (default 10px)
- Shift + Arrow: Resize by larger step (50px)
- Home: Minimize pane to minimum size
- End: Maximize pane to maximum size
- Tab: Navigate between dividers
v3 includes proper ARIA attributes for screen reader support:
role="separator"aria-valuenow,aria-valuemin,aria-valuemaxaria-orientationaria-label
Touch events work out of the box on mobile devices.
Add snap points for commonly used sizes:
<SplitPane
snapPoints={[200, 400, 600]}
snapTolerance={20}
>v3 is written in TypeScript. Import types directly:
import type {
SplitPaneProps,
PaneProps,
DividerProps,
Direction,
Size,
ResizeEvent
} from 'react-split-pane';v3 drops support for IE11. Use v0.1.x if you need IE11 support.
Supported browsers:
- Chrome/Edge (latest 2 versions)
- Firefox (latest 2 versions)
- Safari (latest 2 versions)
- Mobile browsers (iOS Safari, Chrome Android)
If you encounter issues during migration: