v7.0.0
vadimdemedes/inkv7.0.0Apr 8, 2026by sindresorhus
AI Summary
A major version bump introducing React 19 support and Node.js 22 requirements, along with significant new hooks and layout features, while changing keyboard input behavior.
Key Highlights
- Requires Node.js 22 and React 19.2+
- Adds new hooks: usePaste, useWindowSize, useBoxMetrics, useAnimation
- Changes keyboard input: key.backspace vs key.delete, key.meta no longer for Escape
- Adds layout features: wrap="hard", maxWidth, aspectRatio, etc.
Breaking Changes
- Require Node.js 22
- Require React 19.2+
- Pressing Backspace now correctly sets key.backspace instead of key.delete
- key.meta is no longer set to true when Escape is pressed
New Features
- usePaste hook
- useWindowSize hook
- useBoxMetrics hook
- useAnimation hook
- alternateScreen option for render()
- interactive option for render()
- activeId to useFocusManager()
- borderBackgroundColor to Box
- wrap="hard" to Text
- maxWidth and maxHeight props to Box
- aspectRatio, alignContent, position props to Box
- Kitty keyboard protocol auto-mode
Full Release Notes
### Breaking
- Require Node.js 22 19b5316
- Require React 19.2+ cfaebbb
- Ink now uses `useEffectEvent` internally to avoid re-subscribing input handlers on every render
- Pressing Backspace now correctly sets `key.backspace` instead of `key.delete` ([#634](https://github.com/vadimdemedes/ink/issues/634)) 321a2e8
- Most terminals send the same byte for Backspace as the Delete key, which caused Ink to misreport it. If you were checking `key.delete` to handle backspace, switch to `key.backspace`
- `key.meta` is no longer set to `true` when Escape is pressed e195912
- Previously a backward-compat shim made plain Escape set both `key.escape` and `key.meta`. Now only `key.escape` is `true`. `key.meta` is reserved for actual Alt/Meta modifier combinations
### New
- Add [`usePaste`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#usepastehandler-options) hook for handling clipboard paste events fbbeb23
- Automatically enables bracketed paste mode so pasted text arrives as a single string, never misinterpreted as individual key presses by `useInput`
- Add [`useWindowSize`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#usewindowsize) hook 7047795
- Returns `{columns, rows}` and re-renders automatically on terminal resize
- Add [`useBoxMetrics`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#useboxmetricsref) hook for measuring box dimensions at runtime ([#433](https://github.com/vadimdemedes/ink/issues/433)) 88731d1
- Add [`useAnimation`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#useanimationoptions) hook for built-in animation support ([#142](https://github.com/vadimdemedes/ink/issues/142)) ada019c
- Provides a frame counter that increments at a configurable interval, with pause/resume support and automatic cleanup on unmount
- Add [`alternateScreen`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#alternatescreen) option to `render()` ([#263](https://github.com/vadimdemedes/ink/issues/263)) 5a60eb9
- Renders into the terminal's alternate screen buffer (like vim or less), restoring the previous terminal content on exit
- Add [`interactive`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#interactive) option to `render()` (#888) 02490f6
- Override automatic interactive-mode detection for environments where the built-in heuristic doesn't fit
- Add [`activeId`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#activeid) to `useFocusManager()` ([#661](https://github.com/vadimdemedes/ink/issues/661)) eb2f470
- Returns the ID of the currently focused component, or `undefined` if nothing is focused
- Add [`borderBackgroundColor`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#borderbackgroundcolor) (and per-side variants) to `<Box>` (#906) d3c6d14
- Set a background color on borders independently from the box content background
- Add [`wrap="hard"`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#wrap) to `<Text>` (#925) 2b1e3a6
- Fills each line to the full column width, breaking words mid-word as needed
- Add [`maxWidth`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#maxwidth) and [`maxHeight`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#maxheight) props to `<Box>` ([#713](https://github.com/vadimdemedes/ink/issues/713)) 9291794
- Add [`aspectRatio`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#aspectratio), [`alignContent`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#aligncontent), [`position="static"`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#position), and [`top`/`right`/`bottom`/`left`](https://github.com/vadimdemedes/ink?tab=readme-ov-file#position) layout props to `<Box>` c2f4b86
- Kitty keyboard protocol: query all terminals in auto mode instead of a hardcoded allowlist (#895) 3e672b5
### Fixes
- Fix incremental rendering for trailing newline (#910) c32da0b
- Fix `useInput` crash on unmapped key codes (#902) 969a4f1
- Fix CJK text truncation exceeding `<Box>` width b5f3e3a
- Fix splitting wide characters (emoji, CJK) when overlapping writes occur (#930) 06d53f4
- Fix dangling `staticNode` reference (#905) 0dc4dfa
---
## Migration guide
### `key.backspace` vs `key.delete`
```js
// Before — physical backspace was reported as key.delete
useInput((input, key) => {
if (key.delete) { /* was catching physical backspace key */ }
});
// After
useInput((input, key) => {
if (key.backspace) { /* physical backspace key (0x7F) */ }
if (key.delete) { /* actual Delete key (e.g. Fn+Backspace) */ }
});
```
### `key.meta` no longer set on plain Escape
```js
// Before — key.meta was true for both Escape AND Alt+key
useInput((input, key) => {
if (key.meta) { /* fired on plain Escape too */ }
});
// After — check key.escape explicitly for the Escape key
useInput((input, key) => {
if (key.escape) { /* plain Escape */ }
if (key.meta) { /* Alt/Meta combos only */ }
});
```
---
https://github.com/vadimdemedes/ink/compare/v6.8.0...v7.0.0