AI answers shouldn’t outgrow their interface
Introducing gpt_markdown 1.3.0: faster streaming, richer rendering, and more room for what comes next.
An AI answer is not delivered like a finished document. It grows in public: a sentence becomes a list, the list adds a table, and the answer ends with code or an equation. Each new chunk can extend—or reinterpret—what came before. The interface has to keep up while all of this is still being written.
At Val, we’re building the live visual layer for AI agents. That starts with making the output people already use feel fast, readable, and native to their product.
gpt_markdown 1.3.0 is our biggest release yet. Our open-source Flutter renderer now has a new parsing pipeline, lazy rendering for long documents, streaming animations, and built-in syntax highlighting.
In our benchmarks, parsing is 3–9× faster than the legacy parser. At 12 KB, each streaming update is 31× faster with GptMarkdown and 74× faster with the new SliverGptMarkdown than in 1.2.1.
The point isn’t just a faster parser. It’s an interface that keeps up as an answer grows.
See it first
Examples include rich text, inline LaTeX equations, and responsive tables rendered by gpt_markdown 1.3.0.
Part 1 — Speed that lasts beyond the first sentence
A new parser. A faster frame.
The new single-pass parser replaces the legacy regex engine as the default. In equivalent source-to-span workloads, it measured 3–9× faster.
Parsing is only part of the work. Flutter also builds, lays out, and paints the result. Whole-frame benchmarks measured 1.4–2× faster rendering than 1.2.1 across the tested document shapes.
Streaming that keeps up
Rendering a finished answer once is one problem. Updating it on every incoming chunk is another. If each update repeats work across everything already received, longer answers become progressively more expensive to display.
The new pipeline caches settled segments and updates the changing tail. In our measured workloads, per-chunk cost stayed broadly stable as replies grew, instead of increasing with the accumulated answer.
| Reply length | GptMarkdown vs 1.2.1 | SliverGptMarkdown vs 1.2.1 |
|---|---|---|
| 2 KB | 3.8× faster | 7.6× faster |
| 6 KB | 16× faster | 23× faster |
| 12 KB | 31× faster | 74× faster |
These ratios use the more conservative of two runs. The small 2 KB workload was close to the measurement floor; the 12 KB improvement reproduced closely.
Measurements were taken in Flutter’s debug VM on macOS—not production-device frame-rate guarantees. Results vary with hardware, viewport, and content. The benchmark report includes methodology, raw results, and cases where other renderers are faster.
Part 2 — Long answers, one screen at a time
Stable streaming solves repeated work. Long answers introduce a second problem: most of the response is off screen.
Thirty screens of content. One screen of attention. The renderer shouldn’t need to build all thirty at once.
SliverGptMarkdown creates spans and widgets only for document segments requested by the viewport, including its cache extent:
CustomScrollView(
slivers: [
SliverGptMarkdown(longAnswer),
],
)
The source is segmented up front; rendering is lazy. In the longest cold-mount workload tested, the sliver was 6.4× faster than the regular widget.
Which one should you use? Keep GptMarkdown for chat messages, cards, and short content. Use SliverGptMarkdown for long responses or documents in a scrollable viewport.
The regular widget is cheaper for short content and supports character reveal. The sliver displays source updates immediately, and selection covers mounted content. A single large table or code block remains one segment—it is not virtualized internally.
Part 3 — Built for AI chat
Performance keeps an answer moving. Presentation determines whether it feels native to the product around it.
GptMarkdown(
reply,
isStreaming: generating,
animation: GptMarkdownAnimation.fade,
blockAnimation: GptMarkdownBlockAnimation.fadeIn,
)
Choose typewriter, fade, blur, or wave reveals for text. Give tables, code blocks, and images their own block entrances. Timing and curves are configurable, and animations respect reduced-motion settings.
The renderer also handles the details that make AI output usable:
- Rich content together: Markdown, LaTeX, tables, lists, images, and citations.
- Code ready to read: syntax highlighting for nearly 200 languages, language labels, and accessible copy controls.
- Links that behave like text: natural wrapping, baseline alignment, and selection, plus automatic linking of bare URLs.
- Accessibility throughout: text scaling, bidirectional layouts, and a coherent streaming semantics node instead of repeated announcements from individual blocks.
How it compares
Most Flutter Markdown renderers were designed for completed documents. gpt_markdown 1.3.0 is designed for AI output while it is still arriving. That distinction changes both the feature set and the performance curve.
| Capability | gpt_markdown | flutter_markdown_plus | markdown_widget |
|---|---|---|---|
| Incremental streaming | Built in | No | No |
| Per-chunk cost as replies grow | Approximately flat | Grows with the document | Grows with the document |
| Lazy block rendering | Real sliver, built on demand | Parses the complete document | Parses the complete document |
| Character and block animations | Built in | No | No |
| Inline and block LaTeX | Built in | No | No |
| Highlighted code with label and copy control | Built in | Custom implementation | Highlighting only |
This is why a comparison based only on one finished paragraph misses the most important workload. Even so, the architectural difference is visible in finished-message cold mounts, using the same documents and harness:
| Content | vs flutter_markdown_plus | vs markdown_widget |
|---|---|---|
| Links | 4.5× faster | 7.2× faster |
| Bullet lists | 3.1× faster | 4.7× faster |
| Plain prose | 2.4× faster | 2.8× faster |
Streaming is where the difference becomes most visible. At an 18 KB reply, SliverGptMarkdown processed the next chunk in 1.0 ms, compared with 80.2 ms for flutter_markdown_plus and 93.0 ms for markdown_widget—about 80× and 93× faster in that workload.
gpt_markdown is not faster at every isolated construct. Code blocks and some table workloads cost more because the default renderer does more, including syntax highlighting, content-aware sizing, a language label, and an accessible copy control. The full benchmark report documents the methodology, raw results, package versions, and every measured tradeoff.
For AI interfaces, this is the larger shift in 1.3.0: performance no longer has to deteriorate as the answer becomes more useful.
Part 4 — Customize anything
Performance makes a renderer viable. Control makes it part of your product. There are three levels of customization, and most integrations won’t need all three.
Level 1 — Style sheets
Change colors, typography, spacing, and component styles without rebuilding the components. Set defaults app-wide and override individual properties where needed.
Level 2 — Builders
Bring your own code panel, image viewer, or table. Span-based builders let you customize links, citations, and inline code while keeping them part of the text flow.
Level 3 — Invent your own syntax
Render @mentions, #channels, emoji shortcodes, or ticket references with inline patterns. Register custom blocks for callouts, product cards, or charts. Use directives for payloads the Markdown parser should leave untouched.
Your application supplies those components and their behavior. The renderer gives them a place alongside the answer—without a fork.
See the customization documentation for implementation examples.
Part 5 — Get it. Keep your integration.
For a new Flutter AI interface, getting started is one dependency and one widget:
dependencies:
gpt_markdown: ^1.3.0
import 'package:gpt_markdown/gpt_markdown.dart';
GptMarkdown(markdownText)
The widget follows your Flutter theme. Start there, then customize what your product needs.
No APIs have been removed. The legacy parser remains supported, with removal planned for 2.0.0. Passing components or inlineComponents—even an empty list—still selects that legacy path. Migrate those extensions to use the new pipeline.
Links and block elements have a different rendering structure, so existing widget tests may need adjustments. The migration guide covers those changes and the replacement APIs.
Get the package · Try the playground · Read the docs
If your product already renders AI output in Flutter, try one of your real responses in the playground. Then use the migration guide to move without giving up the integration you already built.
Beyond the text box
gpt_markdown makes today’s AI output fast, readable, and native to the product around it. Val takes that direction further: toward AI output people can inspect, interact with, and steer—not just read.
gpt_markdown is our open-source rendering foundation. Fast streaming and room for custom UI are essential to that future. Version 1.3.0 puts those capabilities in developers’ hands today.
Building an AI product that needs richer output than a text box? Request early access to Val.