> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monolex.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# AI-Native Terminal UX Research

> 50-Step analysis on optimal rendering strategies for LLM streaming

# AI-Native Terminal UX Research

## Research Question

**What rendering strategy provides optimal UX for AI-native terminals during high-output scenarios (LLM streaming)?**

## Quick Summary

ACK-based flow control provides superior UX for LLM streaming by reducing emit storms (high frequency → controlled rate) while maintaining visual stability. Traditional fast rendering (Alacritty/Ghostty) optimizes for input latency but causes visible jitter during high-output scenarios.

**The optimal AI-native terminal combines both:**

* Low-latency input path
* ACK-paced output buffering

## The Problem

### Traditional Terminal Behavior

When an LLM streams bulk output rapidly:

```
Without flow control:
├── PTY chunk 1 → emit → render
├── PTY chunk 2 → emit → render
├── PTY chunk 3 → emit → render
├── ...
└── 100 chunks = 100 renders → DOM reflow storm → CRASH
```

**Real-world evidence:**

* [VSCode #119178](https://github.com/microsoft/vscode/issues/119178): Terminal freeze during high output
* [Claude Code #10794](https://github.com/anthropics/claude-code/issues/10794): Crashes during streaming
* [xterm.js #2077](https://github.com/xtermjs/xterm.js/issues/2077): Flow control discussion

### Why Fast Rendering Doesn't Help

Traditional GPU terminals (Alacritty, Ghostty, WezTerm) are optimized for **input latency**:

* Minimize time from keypress to display
* Render every frame as fast as possible

But for LLM streaming, you need **output stability**:

* Minimize visual jitter
* Prevent memory exhaustion
* Maintain smooth scrolling

**These are different optimization targets.**

## The Solution: ACK-Based Flow Control

```
With ACK flow control (Monolex):
├── PTY chunk 1 → process → emit → wait for ACK
├── PTY chunk 2 → process → skip emit (waiting)
├── PTY chunk 3 → process → skip emit (waiting)
├── ACK received → request_full_update → emit latest
└── 100 chunks → 5-10 emits → Stable UI
```

### Key Properties

| Property            | Description                                                    |
| ------------------- | -------------------------------------------------------------- |
| **Consumer-driven** | RAF callback start triggers next emit (not render completion!) |
| **No data loss**    | Grid processes ALL data, only emit is controlled               |
| **O(1) memory**     | Boolean flags, no frame queue                                  |
| **1s fallback**     | Prevents deadlock if ACK lost                                  |

> **Note (2026-01-13):** ACK is sent at RAF callback start, BEFORE inject().
> This provides processing-slot backpressure with \~15ms gap before actual render.

## Evidence Summary

| Source Type        | Count   | Key Sources                                        |
| ------------------ | ------- | -------------------------------------------------- |
| Codebase           | 5 files | lib.rs, atomic\_parser.rs, grid-buffer-injector.ts |
| GitHub Issues      | 6       | VSCode, Claude Code, xterm.js, Ghostty             |
| Documentation      | 4       | xterm.js, WezTerm, iTerm2, Synchronized Output     |
| Terminals Analyzed | 5       | xterm.js, Alacritty, Ghostty, WezTerm, Hyper       |

## Terminal Comparison

### How Each Terminal Handles High Output

| Terminal      | Strategy                           | Result                        |
| ------------- | ---------------------------------- | ----------------------------- |
| **xterm.js**  | Parse callback, no render feedback | Overwhelms at high output     |
| **Alacritty** | Render everything, no batching     | High CPU, all frames rendered |
| **Ghostty**   | Dirty tracking, no backpressure    | Frame tearing under load      |
| **Hyper**     | Size-based 200KB batching          | Better but not optimal        |
| **Monolex**   | ACK-based, consumer-driven         | Adaptive, stable              |

### Why Monolex Is Different

```
┌─────────────────────────────────────────────────────────────────┐
│  OTHER TERMINALS                                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  PTY → Parse → Render → Display                                 │
│                  ↑                                              │
│          No feedback loop                                       │
│                                                                 │
│  Problem: Parser overwhelms renderer                            │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│  MONOLEX                                                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  PTY → Parse → [ACK gate] → Emit → RAF → ACK → Inject → Render  │
│                    ↑                      │                     │
│                    └──────────────────────┘                     │
│                                                                 │
│  Note: ACK at RAF start (~15ms before render)                   │
│  Solution: Processing-slot backpressure controls emit rate      │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
```

## Performance Impact

### Before ACK Flow Control

```
LLM streaming scenario:
- Output: Bulk data rapidly
- Emits: Every chunk
- CPU: High
- UX: Jittery, may crash
```

### After ACK Flow Control

```
Same scenario:
- Output: Bulk data rapidly
- Emits: ACK-paced (controlled rate)
- CPU: Lower
- UX: Smooth, stable
```

## Synchronized Output (BSU/ESU)

The industry has recognized this problem. The **Synchronized Output** spec (CSI ? 2026 h/l) allows applications to bracket atomic updates:

```
ESC [ ? 2026 h   # Begin Synchronized Update (BSU)
... terminal output ...
ESC [ ? 2026 l   # End Synchronized Update (ESU)
```

**Limitations:**

* Requires application cooperation
* Doesn't prevent continuous high output
* Only helps for discrete updates

**Monolex's advantage:** Works regardless of application behavior.

## Recommendations for AI Workloads

### For Terminal Developers

1. **Implement render-completion feedback** - Not just parse-completion
2. **Consumer-driven flow control** - Let renderer pace the producer
3. **O(1) memory during wait** - Don't queue frames, keep latest state

### For AI Application Developers

1. **Use BSU/ESU when available** - Bracket atomic updates
2. **Consider output rate** - Don't overwhelm the terminal
3. **Test with fast terminals** - Alacritty, Ghostty, Monolex

### For Users

1. **Use AI-native terminals** - Terminals designed for high output
2. **Monitor CPU usage** - High CPU = poor flow control
3. **Report crashes** - Help terminal developers identify issues

## Conclusion

Traditional terminal architecture optimizes for the wrong metric when dealing with AI workloads. **Input latency** matters less than **output stability** when streaming LLM responses.

Monolex's ACK-based flow control is the first implementation to solve this at the architectural level, achieving:

* Significant CPU reduction
* Stable UI during high output
* No data loss
* Adaptive to rendering speed

***

*Research completed 2025-12-25. 50-step analysis across 5 investigation threads.*
