How Claude Code renders its terminal UI using a custom React renderer.
What Is Ink?
Ink is a custom React renderer that targets the terminal instead of the DOM. It lets you write terminal UIs using React components and JSX.
TypeScript
// This renders in the terminal, not in a browser
<Box flexDirection="column" padding={1}>
<Textbold>Hello, Terminal!</Text><Textcolor="gray">This is Ink.</Text>
</Box>
Blit optimization: If a subtree hasn't changed, it's bulk-copied from the previous frame's screen buffer instead of re-rendering children:
TypeScript
// In renderNodeToOutput:if (prevScreen && !nodeDirty) {
output.blit(prevScreen, x, y, width, height) // Fast memcpyreturn
}
// Otherwise, render children recursively
5. Diff
The new frame is diffed against the previous frame:
TypeScript
diffEach(prevScreen, nextScreen, (x, y, oldCell, newCell) => {
// Record the change
})
The diff algorithm:
Uses packed Int32Array cells (2 words per cell)
Scans for differences with raw integer comparison
Only iterates the damage union (changed regions)
No object allocation during diff
6. Terminal Output
The diff produces terminal escape sequences:
Plain text
\x1b[H — Cursor home (alt-screen anchoring)
\x1b[2J — Clear screen
\x1b[31mHello — Red text
\x1b[0m — Reset
\x1b[10;20H — Move cursor to row 10, column 20
Key behaviors:
Relative cursor moves: All positioning is relative to previous cursor position
Alt-screen anchoring: Every alt-screen frame prepends cursor home to prevent drift
Cursor parking: Cursor is parked at declared position (for IME input)
Screen Buffer
The Screen is the pixel buffer — a packed Int32Array:
Plain text
Each cell = 2 words (8 bytes):
Word 0: charId (index into CharPool)
Word 1: styleId[31:17] | hyperlinkId[16:2] | width[1:0]
This packed layout halves memory accesses and enables future SIMD comparison.
Style Pool
Interns ANSI style arrays into integer IDs:
TypeScript
// Instead of storing ["\x1b[31m", "\x1b[1m"] per cell,// store a single integer ID that maps to those stylesconst styleId = StylePool.intern(["\x1b[31m", "\x1b[1m"])
Features:
Cached style transitions (transition(fromId, toId)) for zero-allocation ANSI strings
Inverse, selection-bg, and current-match style variants
Bit 0 encodes visibility on spaces
Char Pool
Interns character strings with an ASCII fast-path:
TypeScript
// ASCII characters (code < 128): direct Int32Array lookup// Non-ASCII: interned string with IDconst charId = CharPool.intern("A") // Fast path: returns 65
Key Components
Layout Primitives
<Box>
The fundamental layout primitive — equivalent to <div style="display:flex">: