try it in your terminal — ssh r-that.com
Building a Terminal UI Framework with React and Ink

When I first looked at how Claude Code renders its interface -- spinners, streaming text, interactive menus, all inside a terminal -- I wanted to understand the mechanics behind it. Not just "it uses React," but how React renders to a terminal, how animations run at 20fps without flickering, and how input handling works without a DOM.

The Stack

The answer is Ink, a React renderer for the terminal. Instead of rendering to a browser DOM, Ink renders to stdout using ANSI escape codes. Components like <Box> and <Text> map to terminal layout and styling, and hooks like useInput capture keyboard events.

import { render, Box, Text, useInput } from 'ink';

function App() {
  const [count, setCount] = useState(0);
  useInput((input) => {
    if (input === '+') setCount(c => c + 1);
  });
  return <Box><Text>Count: {count}</Text></Box>;
}

render(<App />);

That's a working interactive terminal app in 10 lines.

What I Built

I created 30 isolated demos, each exploring a specific pattern:

Animations: Claude's exact spinner sequence (· ✻ ✽ ✶ ✳ ✢) with variable frame timing, sub-character progress bars using Unicode block elements, and streaming text with cursor blink.

Interactions: Fuzzy finders with scored ranking, vim-mode text editing with normal/insert/visual modes, checkbox multi-select with bulk operations.

Data Display: Braille-dot line charts, collapsible JSON inspectors, sortable data tables, and GitHub-style contribution heatmaps.

Layout: Split panes with resizable panels, tab navigation, modal dialogs with focus trapping, and a composed mini-dashboard combining all patterns.

Key Takeaway

The terminal is a more capable rendering target than most people assume. With Unicode characters, ANSI colors, and a React component model, you can build interfaces that rival simple web UIs -- all accessible over SSH from any machine.