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