react-virtualized-auto-sizer
react-virtualized-auto-sizer is a React component that observes the size available from its parent HTML element, then passes width and height to a child component or render function. It exists for widgets such as older virtualized lists, canvases, charts, and grids that require numeric pixel dimensions rather than CSS alone. Version 2 uses ResizeObserver when available, includes a legacy fallback, ships TypeScript types, and supports React 18 and 19. It measures layout; it does not virtualize rows or manage data.
A clean, current answer when an older virtualizer or pixel-sized widget truly needs its parent's dimensions. Do not add it reflexively to modern react-window or layouts CSS can express; in those cases it is another observer and render cycle with no benefit.
Use it if
- You use react-virtualized or another component that requires explicit numeric width and height props
- A canvas, chart, grid, or WebGL surface must recalculate from its containing element rather than the browser viewport
- You need one component API that uses ResizeObserver and retains a fallback for environments without it
- You want content-box, border-box, or device-pixel-content-box measurement plus an onResize callback
- You use a current react-window release: this package's README says newer react-window versions observe size natively and do not require AutoSizer
- CSS width: 100%, height: 100%, flex, grid, or container queries can solve the layout without JavaScript pixel values
- You want to measure an arbitrary element from a hook rather than insert an AutoSizer element: react-use-measure or another ResizeObserver hook is a better fit
- Your app is on React 17 or earlier: version 2.0.3 declares only React and React DOM 18 or 19 as peers
- You expect stable dimensions during server rendering with no fallback plan: width and height are undefined on the initial render, including SSR, and v2 removed defaultWidth and defaultHeight props
Setup reality
npm install react-virtualized-auto-sizer has no runtime dependencies, native build, account, credential, or config file. React and React DOM 18 or 19 must already be installed. Version 2 publishes CommonJS, ES module, and TypeScript declaration builds, and AutoSizer is a named export. The largest setup trap is CSS: it measures its parent element, so that parent must already have a real width and height. AutoSizer does not make a zero-height parent grow. Flex layouts often need a dedicated child with flex: 1 1 auto and min-width or min-height set to 0; grid layouts similarly need a bounded track. On the first render and during server rendering, ChildComponent or renderProp receives undefined dimensions. Version 2 removed defaultWidth and defaultHeight, so use default function parameters for a hydration-stable estimate or render a placeholder until both numbers exist. It also removed disableWidth, disableHeight, and doNotBailOutOnEmptyChildren. To ignore one dimension, memoize a ChildComponent with a comparator that only watches the dimension you care about. Prefer a module-level ChildComponent for normal use because AutoSizer memoizes that component; use renderProp when it must close over local state. The deprecated Child alias still works but should not appear in new code. content-box is the default and subtracts parent padding and borders from getBoundingClientRect. border-box keeps them. device-pixel-content-box support varies by browser, so test the target set. ResizeObserver callbacks are deferred with a zero-delay timer to avoid loop-limit failures. Without ResizeObserver the package installs a legacy element-resize mechanism that injects styles; a strict Content Security Policy may require the nonce prop. CSS transforms and transitions have measurement limits, and the changelog says no event announces that a transition has completed. In tests, jsdom does not perform layout, so mock ResizeObserver and the parent's rectangle rather than expecting real dimensions.
Patterns
Measure a bounded parent with ChildComponentmeasure-parent
import { AutoSizer, type SizeProps } from 'react-virtualized-auto-sizer';
function CanvasSurface({ width, height }: SizeProps) {
if (width === undefined || height === undefined) return null;
return <canvas width={width} height={height} />;
}
export function Panel() {
return (
<div style={{ width: '100%', height: 400 }}>
<AutoSizer ChildComponent={CanvasSurface} />
</div>
);
}AutoSizer measures its parent. Give that parent a real height; AutoSizer cannot derive a size from an unbounded or zero-height container.
Use renderProp when local state is neededuse-render-prop
function ChartPanel({ points }) {
const [highlight, setHighlight] = useState(null);
return (
<AutoSizer
renderProp={({ width, height }) =>
width === undefined || height === undefined ? null : (
<Chart
width={width}
height={height}
points={points}
highlight={highlight}
onHighlight={setHighlight}
/>
)
}
/>
);
}Use ChildComponent for better memoization when it does not need to close over the parent's props or state.
Size a react-virtualized Listsize-react-virtualized-list
function SizedList({ width, height }: SizeProps) {
if (!width || !height) return null;
return (
<List
width={width}
height={height}
rowCount={rows.length}
rowHeight={36}
rowRenderer={rowRenderer}
/>
);
}
<div style={{ height: 500 }}>
<AutoSizer ChildComponent={SizedList} />
</div>This is for react-virtualized and other explicit-size widgets. Current react-window releases have native sizing and do not need this package.
Provide initial dimensions with default parametersprovide-ssr-defaults
function ResultsGrid({
width = 800,
height = 600,
}: SizeProps) {
return <Grid width={width} height={height} />;
}
<AutoSizer ChildComponent={ResultsGrid} />Version 2 removed defaultWidth and defaultHeight. Defaults belong on the child parameters and should be chosen to minimize hydration layout shift.
Show a placeholder until measurementrender-size-placeholder
function MeasuredChart({ width, height }: SizeProps) {
if (width === undefined || height === undefined) {
return <ChartSkeleton />;
}
return <Chart width={width} height={height} />;
}Both values are undefined on the first client render and on the server. Zero is a real measured size, so check undefined rather than truthiness when zero matters.
Give AutoSizer a measurable flex parentuse-flex-layout
<div style={{ display: 'flex', width: '100%', height: '100%' }}>
<Sidebar />
<div style={{ flex: '1 1 auto', minWidth: 0, minHeight: 0 }}>
<AutoSizer ChildComponent={ResultsGrid} />
</div>
</div>AutoSizer does not make a flex item grow. The dedicated flex child establishes the available area, and minWidth or minHeight prevents content from forcing overflow.
Re-render only when height changesignore-width-updates
const HeightOnlyChild = memo(
function HeightOnly({ height }: SizeProps) {
return <Timeline height={height ?? 0} />;
},
(previous, next) => previous.height === next.height
);
<AutoSizer ChildComponent={HeightOnlyChild} />Version 2 removed disableWidth and disableHeight. A memo comparator reproduces the useful part by ignoring changes to one dimension.
Include padding and borders in the measurementobserve-border-box
<AutoSizer
box="border-box"
ChildComponent={CanvasSurface}
/>content-box is the default and subtracts the parent's padding and borders. Choose the box that matches the child's sizing contract.
Request device-pixel sizing for a canvasobserve-device-pixels
<AutoSizer
box="device-pixel-content-box"
ChildComponent={HiDpiCanvas}
/>Browser support and reported semantics for device-pixel-content-box vary. Test every supported browser and keep a fallback strategy.
Receive size changes outside the childhandle-resize
<AutoSizer
ChildComponent={ResultsGrid}
onResize={({ width, height }) => {
metrics.record('results-grid-size', { width, height });
}}
/>Resize can fire frequently during layout changes. Keep this callback cheap and rate-limit analytics or persistence work yourself.
Authorize the legacy fallback under CSPset-csp-nonce
<AutoSizer
nonce={cspNonce}
ChildComponent={ResultsGrid}
/>The nonce is used only by the stylesheet-based fallback in browsers without ResizeObserver. Modern ResizeObserver paths do not need injected fallback styles.
Migrate the v1 children function to v2migrate-v1-render-child
// v1:
// <AutoSizer>{({ width, height }) => <Grid width={width} height={height} />}</AutoSizer>
// v2:
<AutoSizer
renderProp={({ width = 800, height = 600 }) => (
<Grid width={width} height={height} />
)}
/>The v1 children-function API and defaultWidth or defaultHeight props are gone. Use renderProp and parameter defaults in version 2.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| react-window | npm | Use its current native sizing support when the actual goal is a new virtualized list or grid. |
| react-use-measure | npm | Use it when a hook and ref should measure any element without inserting an AutoSizer wrapper component. |
| react-resize-detector | npm | Use it when you prefer a hook or component with debounce and throttle conveniences around ResizeObserver. |
| @react-hook/resize-observer | npm | Use it for a small hook focused directly on observing an element ref. |