Background knowledge for building ink 7 (React terminal renderer) components, hooks, and patterns. Apply when creating or modifying terminal UI.
Box - flexbox container. Props: flexDirection, alignItems, justifyContent, padding, paddingX, paddingY, margin, marginX, marginY, borderStyle ("single", "round", "double", "bold"), borderColor, width, height, minWidth, minHeight, gapText - styled text. Props: color, backgroundColor, bold, italic, underline, strikethrough, dimColor, inverse, wrap ("wrap", "truncate", "truncate-end", "truncate-middle", "truncate-start")Newline - line break (use inside Text)Spacer - flexible space (fills available space in a Box)Static - renders items once, not re-rendered. For persistent output above dynamic area. Takes items array and render function as children.Transform - wraps children, applies string transformation via transform propAll text must be wrapped in <Text>. Raw strings outside <Text> cause errors.
useInput((input: string, key: Key) => {
if (input === ' ') { /* space pressed */ }
if (key.return) { /* enter pressed */ }
if (key.escape) { /* escape pressed */ }
}, { isActive: true });
Key fields: upArrow, downArrow, leftArrow, rightArrow, return, escape, ctrl, meta, shift, tab, backspace, delete
Returns { exit(error?) }. Call exit() to quit the app cleanly.
Returns { isFocused }. Options: { autoFocus, id }. Tab cycles focus.
Returns { focusNext(), focusPrevious(), focus(id), enableFocus(), disableFocus() }.
Low-level stream access. useStdin() returns { stdin, isRawModeSupported, setRawMode }.
import { render } from 'ink';
const instance = render(<App />, {
exitOnCtrlC: true, // default: true
});
// instance.rerender(<App updated />)
// instance.unmount()
// await instance.waitUntilExit()
useEffect(() => {
const id = setInterval(() => fetchData(), 5000);
return () => clearInterval(id);
}, []);
const { exit } = useApp();
useInput((input, key) => {
if (input === 'q') exit();
if (input === ' ') togglePlay();
});
<Box flexDirection="column" padding={1}>
<Text bold>Title</Text>
<Box marginTop={1}>
<Text dimColor>hint text</Text>
</Box>
</Box>
import { render, Box, Text, useInput, useApp } from 'ink';
import type { Key } from 'ink';
import { useState, useEffect, useCallback } from 'react';
Use import type for type-only imports. Use .js extension for relative imports.