[FEATURE] Add native markdown rendering
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Problem
When Claude wants to display a table, it generates box-drawing characters (┌─┬─┐, │, ├─┼─┤, etc.) token by token. This is expensive:
- A 6-row, 4-column table is ~1800 chars as box-drawing vs ~600 chars as markdown — 3x more output tokens
- Each box-drawing character (
─,│,┼, etc.) is its own token - The model has to compute column widths and alignment padding across all rows before it can start emitting — wasted compute for an autoregressive model that can't look ahead
Impact
Tables are common in Claude Code output (comparisons, summaries, data analysis). Saving ~2/3 of tokens on every table adds up, especially in long sessions. Beyond tokens, removing the alignment computation lets the model focus on content.
Related issues
- #16772 — requested table rendering style options (auto-closed, no response)
- #44696 — wide markdown tables collapsing into unusable card format
- #44422 — plan dialog overlapping table content
Proposed Solution
The model should output markdown tables as the canonical format, and the client should handle rendering:
- TUI: Render markdown tables as box-drawing art (trivial — ~50 lines of Python, I have a working prototype)
- Claude Desktop / web: Render as HTML tables
- IDE extensions: Render using whatever the IDE supports
This cleanly separates content from presentation. The model produces the data, each client renders it appropriately for its medium.
Alternative Solutions
I tried having the model write a markdown table to a temp file, then pipe it through a formatting script. This works, but Bash tool output gets truncated in the TUI ("... +N lines, ctrl+o to expand"), which defeats the purpose. There's no setting to control this truncation.
Priority
Medium - Would be very helpful
Feature Category
Interactive mode (TUI)
Use Case Example
Use case example
I asked Claude Code to research some data and summarize findings. It produced a comparison table:
┌──────────────┬───────┬──────────┬──────────────────────────────┐
│ Component │ Score │ Volume │ Notes │
├──────────────┼───────┼──────────┼──────────────────────────────┤
│ service-a │ 26.0 │ 421K │ Already optimized │
├──────────────┼───────┼──────────┼──────────────────────────────┤
│ service-b │ 13.0 │ 722K │ Strongest remaining candidate│
├──────────────┼───────┼──────────┼──────────────────────────────┤
│ service-c │ 26.0 │ 134K │ Worth investigating │
└──────────────┴───────┴──────────┴──────────────────────────────┘
The identical content as a markdown table:
| Component | Score | Volume | Notes |
|---|---|---|---|
| service-a | 26.0 | 421K | Already optimized |
| service-b | 13.0 | 722K | Strongest remaining candidate |
| service-c | 26.0 | 134K | Worth investigating |
The box-drawing version is 3x the characters, and the model had to compute that every column lines up perfectly before emitting the first character. If the TUI rendered the markdown table visually, the user sees the same pretty output while the model only pays for the compact format.
Additional Context
_No response_
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗