mrkeyoor.com_
Fri 07 Aug 22:55 UTC
npmWeb Frontendupdated 07 Aug 2026

react-textarea-autosize

react-textarea-autosize is a drop-in replacement for the textarea element that grows and shrinks as the user types. It renders a real textarea, forwards every prop and the ref to it, and adds four of its own: minRows, maxRows, onHeightChange and cacheMeasurements. Height is worked out by measuring a hidden copy of the element with your computed styles applied, so it respects your font, padding and line height rather than guessing. The whole thing is 1.6 KB gzipped over three small dependencies, and the peer range covers React 16.8 through React 19.

Verdict

Still the default answer for an auto-growing textarea in React: tiny, prop-compatible with the real element, and stable enough that sixteen months without a commit has not hurt anyone. Check whether CSS field-sizing covers your browsers first, because that is a dependency you do not have to ship.

API stability5/5Four extra props and everything else forwarded to the textarea; the 8.x line has held that surface for years and the peer range was widened to React 19 without a breaking change
Docs2/5The README documents all four props in a table and links a live demo, but the usage example calls React.renderComponent (removed from React a decade ago), it still claims IE9 support, and the styling requirements that cause most real bugs are not mentioned at all
Maintenance2/5No commit since 2025-03-30 and 60 open issues on a single-maintainer project; it is not archived or deprecated and the component is small enough to keep working, but nobody is fixing anything right now
Ecosystem4/58.5M weekly downloads and 1.6 KB gzipped, compatible from React 16.8 to 19, and it drops into any form library because it forwards props and refs; there is nothing to extend and no plugin surface

Use it if

  • You need a chat, comment or prompt input that expands with the message, which is the case this component is built for
  • You want to keep using a plain textarea with your existing props, styles and form library rather than adopting a component library
  • You need to react to the height change itself, for example to keep a scroll container pinned to the bottom, which onHeightChange gives you
  • You have to support browsers where the CSS field-sizing property is not available yet
Skip it if

Setup reality

Installation is one small package and there is no provider, no CSS file and no configuration. Everything that goes wrong goes wrong in styling. The measurement copies your computed styles, so a stylesheet that lands after mount, a font that swaps in later, or a container that changes width without a re-render leaves the height stale. Set resize: none yourself or the browser's drag handle fights the automatic sizing, and be deliberate about box-sizing since padding and borders feed straight into the calculation. maxRows caps the growth but you still want overflow to be sensible past that point. In server rendered pages the first paint uses whatever rows the browser defaults to and the real height appears after hydration, which reads as a small jump.

Patterns

Controlled auto-growing textareabasic

import TextareaAutosize from 'react-textarea-autosize';

function Composer({ value, onChange }) {
  return (
    <TextareaAutosize
      value={value}
      onChange={(e) => onChange(e.target.value)}
      placeholder="Write a message"
    />
  );
}

It is the default export, and every standard textarea prop (name, disabled, onKeyDown) passes straight through.

Set a floor and a ceiling on the heightrow-bounds

<TextareaAutosize minRows={3} maxRows={10} value={value} onChange={onChange} />

Rows are computed from the measured line height, so a font change moves the actual pixel height that minRows and maxRows produce.

Style it so the sizing is not foughtstyling

<TextareaAutosize
  style={{
    boxSizing: 'border-box',
    resize: 'none',
    width: '100%',
    overflow: 'auto',
  }}
  maxRows={8}
/>

resize: none stops the browser handle from setting an inline height that the component then keeps overwriting.

React to the height changingheight-change

<TextareaAutosize
  onHeightChange={(height, { rowHeight }) => {
    scrollerRef.current?.scrollTo({ top: scrollerRef.current.scrollHeight });
  }}
/>

The second argument carries rowHeight, which is how you convert the pixel height back into a row count if your layout thinks in rows.

Skip re-measuring on every keystrokecache-measurements

<TextareaAutosize cacheMeasurements minRows={2} value={value} onChange={onChange} />

Off by default for a reason: cached measurements go stale when the font, width or padding changes, so only enable it where those are fixed.

Get a ref to the underlying textarearef-focus

const textareaRef = useRef(null);

<TextareaAutosize ref={textareaRef} />

// later
textareaRef.current?.focus();
textareaRef.current?.setSelectionRange(0, 0);

The ref is the real DOM node, so selection, focus and scroll APIs all work as they would on a plain textarea.

Submit on Enter, newline on Shift+Entersubmit-on-enter

<TextareaAutosize
  value={value}
  onChange={(e) => setValue(e.target.value)}
  onKeyDown={(e) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      send(value);
      setValue('');
    }
  }}
/>

Clearing the controlled value shrinks the box back to minRows on the next render, so no manual reset is needed.

Use it with a form libraryform-library

const { ref, ...field } = register('bio');

<TextareaAutosize {...field} ref={ref} minRows={4} />

Because props and ref are both forwarded, anything expecting a native textarea (react-hook-form, Formik, a plain uncontrolled form) works unchanged.

Force a remeasure after a late web fontrecalc-after-font

const [fontsReady, setFontsReady] = useState(false);

useEffect(() => {
  document.fonts?.ready.then(() => setFontsReady(true));
}, []);

<TextareaAutosize key={String(fontsReady)} value={value} onChange={onChange} />

There is no imperative recalculate API, so changing the key to force a remount is the practical workaround for styles that arrive after mount.

Import it from CommonJScommonjs

const TextareaAutosize = require('react-textarea-autosize').default;

The .default is required; the package ships an exports map with both builds, so bundlers pick the right one on their own.

Test it with react-test-renderertest-renderer

const tree = renderer
  .create(<TextareaAutosize />, {
    createNodeMock: () => document.createElement('textarea'),
  })
  .toJSON();

Straight from the README: react-test-renderer calls ref callbacks with null, so without createNodeMock the component has nothing to measure.

Check whether you need it at allcss-alternative

textarea {
  field-sizing: content;
  min-height: 3lh;
  max-height: 10lh;
  resize: none;
}

Where this CSS is supported it replaces the component outright; verify against your own browser matrix rather than assuming, and keep the component as the fallback if you cannot.

Alternatives

PackageRegistryPick it when
autosizenpmYou are not on React, or you want to attach the behaviour imperatively to a textarea you did not render
@mui/materialnpmYou already use MUI and would rather take its TextareaAutosize than add a separate dependency