Skip to content

Stream

Real-time text streaming.


Purpose

Display AI output as it generates — character by character or chunk by chunk.

Use <stream> when you want users to understand that the response is still in progress rather than reading a completed block that appears all at once.


Try it Live

editor.g
12345678910111213141516171819

Edit the Grain document and inspect the rendered preview beside it.

preview

Interactive preview initializes after hydration.

Interactive preview initializes after hydration. Open the docs preview at /grain/; the site is mounted under the project base path.

G-Lang

grain
<stream speed="normal" cursor="true" markdown="false">
  Hello! This text streams in real-time.
</stream>

Attributes

AttributeTypeDefaultDescription
speedfast | normal | slownormalStreaming speed
cursortrue | falsetrueShow blinking cursor
markdowntrue | falsefalseParse markdown

States

IDLE → GENERATING → COMPLETE

PAUSED

RESUMING

ERROR

Events

EventPayloadDescription
stream.start{ content: string }Stream began
stream.chunk{ chunk: string, index: number }New chunk
stream.complete{ fullContent: string }Stream finished
stream.pause{ index: number }Stream paused
stream.error{ error: string }Stream failed

Examples

Basic

grain
<stream>Hello world</stream>

With cursor

grain
<stream cursor="true">Typing...</stream>

Fast streaming

grain
<stream speed="fast">This appears instantly.</stream>

Markdown content

grain
<stream markdown="true">
  # Hello

  This is **bold** and *italic*.

  ~~~javascript
  console.log('Hello');
  ~~~
</stream>

Web Output

html
<grain-stream class="normal" cursor="true" data-speed="normal">
  Hello world
</grain-stream>

Production Guidance

  • Keep stream content user-facing. Hidden reasoning belongs in <think>, not <stream>.
  • Use explicit state transitions so adapters can distinguish active generation, pause, resume, and completion.
  • Pair long-running streams with <state> or <tool> when the UI should explain why output is delayed.

Released under the MIT License.