Problem Statement
When a streamed (or static) response contains a large code block or table, it grows without bound and pushes everything else off-screen. The user has to scroll past hundreds of lines of code just to see the next paragraph. During streaming (isAnimating={true}) the problem is worse: new lines are appended at the bottom but the container keeps growing, so the user constantly loses their place.
Current behavior in the codebase:
| Element |
Container file |
Overflow handling |
Height constraint |
| Code block body |
lib/code-block/body.tsx |
overflow-hidden — content is clipped, not scrollable |
None (auto) |
| Code block wrapper |
lib/code-block/container.tsx |
None (uses content-visibility: auto) |
None |
| Table wrapper |
lib/table/index.tsx |
overflow-x-auto overflow-y-auto |
None (auto) |
Because there is no max-height, both code blocks and tables expand to their full content height regardless of how long they are.
Proposed Solution
1. Constrain height with max-height + vertical scroll
Apply a sensible default max-height (e.g. 400px for code blocks, 300px for tables) so that long content becomes scrollable instead of stretching the page. The feature should be on by default but allow consumers to override or disable it.
2. Auto-scroll to bottom during streaming
When isAnimating is true and new content is appended, the scrollable container should automatically stay pinned to the bottom - just like a terminal emulator.
If the user manually scrolls up to read earlier content, auto-scroll must pause (scroll-anchoring pattern). It re-engages only if the user scrolls back to the bottom, or when a new streaming response begins.
Auto-scroll applies only during streaming (isAnimating={true}), not during static rendering.
Proposed API
<Streamdown
isAnimating={isLoading}
codeBlockMaxHeight={400} // default: 400 (px). Set to 0 or Infinity to disable.
tableMaxHeight={300} // default: 300 (px). Set to 0 or Infinity to disable.
>
{streamingContent}
</Streamdown>
Both props are optional. When omitted, the defaults kick in.
Alternatives Considered
No response
Use Case
Priority
Important
Contribution
Additional Context
No response
Problem Statement
When a streamed (or static) response contains a large code block or table, it grows without bound and pushes everything else off-screen. The user has to scroll past hundreds of lines of code just to see the next paragraph. During streaming (
isAnimating={true}) the problem is worse: new lines are appended at the bottom but the container keeps growing, so the user constantly loses their place.Current behavior in the codebase:
lib/code-block/body.tsxoverflow-hidden— content is clipped, not scrollableauto)lib/code-block/container.tsxcontent-visibility: auto)lib/table/index.tsxoverflow-x-auto overflow-y-autoauto)Because there is no
max-height, both code blocks and tables expand to their full content height regardless of how long they are.Proposed Solution
1. Constrain height with
max-height+ vertical scrollApply a sensible default
max-height(e.g.400pxfor code blocks,300pxfor tables) so that long content becomes scrollable instead of stretching the page. The feature should be on by default but allow consumers to override or disable it.2. Auto-scroll to bottom during streaming
When
isAnimatingistrueand new content is appended, the scrollable container should automatically stay pinned to the bottom - just like a terminal emulator.If the user manually scrolls up to read earlier content, auto-scroll must pause (scroll-anchoring pattern). It re-engages only if the user scrolls back to the bottom, or when a new streaming response begins.
Auto-scroll applies only during streaming (
isAnimating={true}), not during static rendering.Proposed API
Both props are optional. When omitted, the defaults kick in.
Alternatives Considered
No response
Use Case
Priority
Important
Contribution
Additional Context
No response