Breaking
- Require React 19.3+ 7829102
minWidthandmaxWidthon<Box>now only accept numbers (#1029) 7cd7fd9- Percentage strings were never documented as supported, and Yoga resolved them against the wrong ancestor
stdin,stdout, andstderrare now typed as generic Node.js streams (#981) eb82d8f- This applies to the
render()options and touseStdin(),useStdout(), anduseStderr(). TTY-only properties likestdout.columnsare no longer part of the types
- This applies to the
useInputno longer receives unrecognized terminal control sequences (#1014) c76893e- Mouse reports, focus in/out events, cursor position reports, and other terminal replies used to arrive in
inputwith the ESC stripped, as if typed. They are now dropped
- Mouse reports, focus in/out events, cursor position reports, and other terminal replies used to arrive in
New
- Add
contentOffsetXandcontentOffsetYprops to<Box>for building scrollable views (#765) 3ba5828- Combine with
overflow="hidden". See the scroll example
- Combine with
- Add
clientWidthandclientHeighttouseBoxMetrics()andmeasureElement()(#988) 3ba5828- The element size excluding borders, which is the space its content can occupy
- Accept any Node.js stream for the
stdin,stdout, andstderroptions ofrender()(#981) eb82d8f- For example,
PassThroughor otherReadable/Writablestreams. Raw mode is used only whenstdinis a TTY withsetRawMode()
- For example,
- Skip unchanged line prefixes in
incrementalRenderingmode (#1036) 91eb50a- Only the changed part of a line is written, which reduces output and flicker
- Drop the
wsdependency in favor of the nativeWebSocketfor React DevTools (#976) 33567ed - Recognize application keypad Enter as
key.returnb73ebf4
Fixes
Rendering
- Preserve scrollback when clearing the viewport (#994) fe1d123
- Preserve terminal history after
clear()494ebeb - Restore the unchanged frame when rerendering after
clear()fc358c2 - Redraw the frame when the terminal loses rows (#1025) f603aeb
- Keep content above the frame when rows shrink while the cursor is shown (#1031) c800284
- Keep the cursor on the last line when output has no trailing newline (#982) cdc18fa
- Restore the terminal cursor below the frame on exit 06385e9
- Preserve the cursor position when its component skips rendering 013feb2
- Fix incremental rendering of single-line updates, new blank rows, and changed rows (#1039) 9a501e4 507c0c9 509ea75
- Fix overflow clipping when both the shorthand and an explicit axis are set, and preserve
<Transform>line indices when clipping 4f3c7aa - Fix background color inheritance for
<Static>and nested<Text>753a5f8 - Fix fractional percentages being truncated in layout sizes, and restore layout defaults when style props are
undefined274b15a - Preserve visibility across Suspense transitions fc685bc
- Call
onRenderafter the frame is written 83d7de5
<Static>
- Stop replaying
<Static>output on full-clear frames (#1005) d661543 - Replay
<Static>output when resuming re-enters the alternate screen (#1012) 9235028 - Fix repeated padding, ignored margins, and output inside hidden ancestors 793fe59
- Keep
<Static>output after abandoned concurrent renders 8678b76 - Reset captured
<Static>output when its identity changes cfdd9e6 - Preserve blank
<Static>rows f6b2620 c0fa4ef 5911f44 - Fix dangling
staticNodereference on indirect subtree removal (#979) 5448e6b
Text
- Truncate each line of multi-line text separately (#1006) 4b44934
- Keep text at its natural width when there is no room to wrap (#1022) 36f5624
- Fix multi-line
<Text>vanishing when it starts above the top of the output (#1001) 77aba4a - Strip control characters (except tab and newline) from text content (#1020) 405f751 2fbc26a
- Expand tabs, and fix CRLF text overwriting box borders and zero-width spaces overwriting surrounding output 32dc266
- Preserve ANSI styles across explicit newlines b419e5c
- Preserve combining marks across nested text styles 80b1c9c
- Normalize colon and C1 SGR sequences before layout (#1019) b0dfd61 9dfe137 7fe1577
- Preserve styles and columns on clipped or overwritten wide characters f7e57a5 064df65
- Remeasure text when its wrapping mode or
<Transform>wrap points change fc685bc 9c323f6 - Preserve the available width when measuring truncated text 1e57b23
- Fix crashes from invalid color names, and whitespace handling in RGB colors 3be9ed7
Input
- Fix legacy keyboard modifiers, modified SS3 keys, and Kitty keyboard parsing and detection 2ee828c
reportAssociatedTextnow enablesreportAllKeysAsEscapeCodesautomatically
- Handle Ctrl+C that arrives together with ordinary input 13707d2
- Do not mutate the caller's buffer when parsing Meta keys 36d7739
- Keep
onKittyQueryResponsestable acrossrerender()calls (#1007) 70beca5 - Defer input hook side effects while the terminal is suspended (#1016) 61004d7
- Make
suspendTerminal()handles idempotent, and do not restore input modes that were released or belong to an unmounted app a7297c4 b35e89a c613707 - Preserve output during non-interactive terminal suspension a6789fb
Focus
- Treat components that share a focus ID as one Tab stop (#1026) 02ae1e5
- Make
disableFocus()blur the focused component as documented, and respect it when new components auto-focus d130588 - Prevent collisions in automatically generated focus IDs d130588
- Treat an empty string as a valid focus ID f6f7dc7
Other
- Fix screen-reader output: semantic text and labels, empty
<Transform>labels, rewrapping when the terminal widens, and restoring output after console writes (#1028) f480301 bebfe2d - Fix error source excerpts for file URLs and multiline messages, and treat non-Error throws as rendering failures 81e2451
- Fix
renderToString()swallowing thrownundefined, and run effect cleanup when output rendering fails 9f7c1d0 - Fix
useWindowSize()missing resizes before it subscribes fab670b - Track box metrics when a child attaches the ref after mount 53244dc
- Reset
useAnimation()values while paused f25d312 - Use defaults for
render()options that areundefined659249d - Fix unbounded text caches (#986) ad9e3ea
- Fix
wrapTextcache returning results for the wrong text or width (#998) 3809acc - Free the root Yoga node on unmount (#999) 064b4f6
- Avoid retaining an exit listener when calling
waitUntilExit()after unmount 1fcd380
Migration guide
React 19.3
Upgrade react (and @types/react) to 19.3 or later.
minWidth and maxWidth
Use a number. If you need a relative minimum or maximum width, compute it from useWindowSize() or useBoxMetrics() of the parent.
-<Box minWidth="50%">
+<Box minWidth={Math.floor(columns / 2)}>Stream types
useStdout().stdout is now typed as NodeJS.WritableStream, so TTY properties like columns and rows are no longer available in the types. Use useWindowSize() instead, which also re-renders on resize.
-const {stdout} = useStdout();
-const width = stdout.columns;
+const {columns: width} = useWindowSize();Control sequences in useInput
If your useInput handler parsed mouse reports, focus events, or other terminal replies from input, it will no longer receive them. Keys that Ink recognizes, including Kitty keyboard protocol events, are not affected.