AI Assistant

Claude Code's UI is built from React components that render to the terminal via the custom Ink reconciler. Components are organized by domain (messages, permissions, tasks, input, MCP, diffs, and dialogs), each providing a self-contained piece of the interface.

Component Categories

The message rendering system handles the conversation display:

  • Message: renders a single conversation message (user, assistant, system, or tool result) with appropriate styling and content blocks
  • MessageRow: wraps a message with metadata (timestamp, token count, model name) and layout
  • VirtualMessageList: virtualized scrollable list of messages. Only renders messages visible in the viewport, with a JumpHandle ref for programmatic scrolling. Handles scroll-to-bottom behavior and search highlighting

Messages support rich content including code blocks with syntax highlighting, markdown rendering, images (via terminal image protocols), and collapsible tool use/result pairs.

Design System

The design system provides foundational components used throughout the application:

Dialogcontainer
Modal overlay with backdrop, focus trap, and keyboard dismiss (Escape).
Panecontainer
Bordered content panel with optional title, used by /doctor and settings screens.
Tabsnavigation
Tab bar with keyboard navigation and content switching.
StatusIconindicator
Status indicators using Unicode figures (check, cross, spinner, warning).
Spinner / SpinnerWithVerbindicator
Animated spinners with optional action text and multiple modes (thinking, executing, etc.).
PressEnterToContinuecontrol
Blocking prompt that waits for Enter key before proceeding.
LogSelectorpicker
Scrollable list picker for selecting from session logs.
ValidationErrorsListdisplay
Formatted list of validation errors with severity coloring.

State Integration

Components access and update state through two primary hooks:

// Read AppState reactively (re-renders on change)
const appState = useAppState()

// Get the setter for AppState updates
const setAppState = useSetAppState()

// Update state immutably
setAppState(prev => ({
  ...prev,
  thinkingEnabled: true,
}))

Components also use the useKeybinding and useKeybindings hooks from the keybindings system for keyboard shortcut handling, and useTerminalSize for responsive layout.

Rendering Hooks

Several custom hooks support the rendering pipeline:

useSearchHighlighthook
Provides search term highlighting across rendered content.
useTerminalFocushook
Tracks whether the terminal window has OS-level focus.
useTerminalTitlehook
Sets the terminal window title.
useTabStatushook
Sets the terminal tab status line (in supported terminals).
useTerminalNotificationhook
Sends desktop notifications via terminal escape sequences.
useFpsMetricshook
Tracks frames-per-second for performance monitoring.
useAfterFirstRenderhook
Defers work until after the first frame is painted.