React in the Terminal: Ink 7.0 fundamentally revises input handling
Ink 7.0 revises input handling and brings new hooks for animation, paste, and responsive layouts. Node.js 22 and React 19.2 are now required.
(Image: Ink)
With version 7.0.0, the React-based CLI library Ink significantly raises its minimum requirements and fundamentally revises input handling. At the same time, new APIs for interactivity, layout, and animation are added. The maintainers will require Node.js 22 and React from version 19.2 onwards. The changes require adjustments in existing projects but also enable more complex terminal UIs.
Ink allows interactive command-line applications to be developed declaratively with React components. Instead of working directly with ANSI escape sequences and low-level terminal APIs, developers define their CLI interfaces similarly to web UIs – with state management, component structure, and hooks.
Breaking Changes in Input Handling
Internally, Ink now uses React's useEffectEvent to prevent input handlers from re-registering on every render. This stabilizes event handling and reduces performance overhead.
There are also corrections in processing keyboard input. For example, Ink now clearly distinguishes between key.backspace and key.delete. Many terminals send identical byte sequences for both keys, which previously led to misinterpretations. Anyone who previously reacted to key.delete to catch backspace must adjust their logic. Furthermore, Ink no longer sets key.meta when the escape key is pressed: key.meta now exclusively signifies Alt/Meta combinations, while key.escape is indicated separately.
New Hooks for Interactivity and Animation
The new hook usePaste handles pasted text from the clipboard as a separate event. To achieve this, Ink activates the terminal's Bracketed Paste mode, ensuring that pasted text arrives as a contiguous string. Without this mode, a paste operation would appear as a series of individual keypress events – which is problematic for input fields or REPL-like interfaces, for example.
For responsive layouts, the new hook useWindowSize provides the current terminal size in columns and rows and automatically triggers a re-render upon changes. This allows tables or layouts to be dynamically adapted to different terminal sizes.
With useBoxMetrics, developers can determine the actual dimensions of layout containers at runtime – comparable to DOM measurements in the browser. This leads to more precise layout logic when content needs to be positioned or truncated based on the rendered size.
The hook useAnimation brings an integrated animation mechanism. It provides a frame counter that increments at configurable intervals and can be paused. It automatically cleans up upon unmount. Typical use cases include spinners, progress indicators, or ASCII animations.
Videos by heise
Rendering and Layout Extensions
A new Alternate Screen mode is added for rendering. When activated during the render() call, the application uses the terminal's second screen buffer – a behavior known from programs like Vim or less. After exiting, the terminal restores the original content. Additionally, the new option interactive allows overriding the automatic detection of interactive environments, for example, for CI pipelines or pipe scenarios.
The layout system also receives extensions. The component <Box> now supports aspectRatio, alignContent, position="static", as well as position specifications like top, right, bottom, and left. It also includes maxWidth and maxHeight. With borderBackgroundColor, the background color of borders can be set independently of the content for the first time. For text, Ink introduces the option wrap="hard": It strictly fills lines to the available width, breaking even in the middle of words – useful for tabular or strictly aligned monospace layouts.
In focus management, the hook useFocusManager now additionally provides the ID of the currently focused element. This facilitates the control of more complex interactions and troubleshooting.
Bugfixes
In addition to functional innovations, version 7.0.0 fixes several stability issues. These include display errors with CJK texts and emojis, crashes with unknown key codes in input handling, and rendering errors with trailing line breaks and overlapping write operations.
All information about the new version 7.0.0 can be found in the Release Notes on Ink's GitHub project page.
(fo)