Advanced
Terminal UI Rendering
How React draws interfaces in your terminal, not a browser
~5 min read
0
React components
0
Ink engine files
0
Renderer LOC
You know how websites use React to draw buttons, text, and layouts in a browser? Claude Code does the same thing — but in your terminal. It uses a library called Ink that takes React components and renders them as terminal text with colors, boxes, and interactive elements.
Think of it like this: React is the architect, Ink is the builder, and your terminal is the construction site. The architect draws the same blueprints, but instead of building with HTML and CSS, the builder uses ANSI escape codes (the terminal's 'paint').
Rendering Pipeline #
From React components to terminal pixels
React Tree
Ink Reconciler
Yoga Layout
ANSI Output
Terminal Screen
Ink vs Browser React #
Same programming model, different output targets
| Aspect | Browser React | Ink (Terminal) |
|---|---|---|
| Reconciler | react-dom (maps to HTML DOM) | Custom Ink reconciler (maps to terminal nodes) |
| Layout Engine | CSS + Browser layout engine | Yoga (cross-platform Flexbox) |
| Output | HTML elements + CSS styles | ANSI escape sequences |
| Events | DOM events (click, keydown, etc.) | stdin parsing (key presses, mouse sequences) |
| Styling | CSS classes + inline styles | ANSI color codes + chalk library |
Design Highlights #
What makes terminal React work
Full Flexbox in Terminal
Yoga provides real CSS Flexbox layout — not approximate text alignment, but proper flex-grow, justify-content, align-items, wrapping, and absolute positioning. Terminal UIs feel like web UIs.
Keyboard & Mouse Events
Ink's event system captures keyboard shortcuts, mouse clicks (with hit-testing against layout), focus management, and even hyperlink detection. Terminal apps feel interactive, not static.
Incremental Rendering
Only changed regions of the terminal are redrawn — React's reconciliation algorithm ensures minimal screen updates, preventing flicker during streaming output.
Related Pages
← → arrow keys to navigate