Contributors Forks Stargazers Issues License Pub Version


animated_streaming_markdown logo

animated_streaming_markdown

Streaming Markdown parser + renderer for Flutter, optimized for incremental append flows. Native targets and Flutter web are supported, including zero-config Tree-sitter WASM assets for published builds.
Explore the docs »

View Demo · Report Bug · Request Feature

Latest Update

  • Flutter web is first-class: published builds include the generated Tree-sitter WASM parser asset, so app developers do not need to edit web/index.html or copy files manually.
  • KaTeX-style LaTeX rendering: inline $...$ / \(...\) and display $$...$$ / \[...\] math now render through flutter_math_fork, a pure Dart/Flutter KaTeX parser and renderer.
  • Real chatbot example: the example app can connect to local Ollama plus ChatGPT/OpenAI, Claude, Gemini, and Grok-compatible cloud APIs.
  • 0.3.5 hotfix: pub.dev platform metadata now explicitly declares Flutter web support to match the shipped WASM-backed implementation.
Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. Documentation
  5. Roadmap
  6. Contributing
  7. License
  8. Contact
  9. Acknowledgments

About The Project

animated_streaming_markdown provides 2 main layers:

  • Parser: MarkdownStreamParser for typed replace/append requests
  • Renderer: AnimatedStreamingMarkdown for block rendering, token reveal animations, inline images, links, selection, and KaTeX-compatible LaTeX math
  • Tables: stable shared-width Markdown tables with left-aligned viewport framing and row-by-row reveal during streaming

It is designed for chat-like or streaming text interfaces where markdown arrives progressively and needs stable UI updates.

(back to top)

Built With

  • Flutter
  • Dart
  • Tree-sitter

(back to top)

Getting Started

Prerequisites

  • Flutter >=3.0.0
  • Dart SDK >=3.0.0 <4.0.0
  • Native toolchain for your target platform (Android/iOS/macOS/Linux/Windows)
  • No extra setup is required for Flutter web consumers; the package ships the generated WASM parser asset and falls back safely when needed.

Installation

  1. Add dependency:
    dependencies:
     animated_streaming_markdown: ^0.3.5
    
  2. Install packages:
    flutter pub get
    

(back to top)

Usage

1) Start parser worker and stream markdown

final parser = MarkdownStreamParser();
await parser.start();

final setResult = await parser.replace('# Hello');

final appendResult = await parser.append('\n\nStreaming **markdown** chunk...');

2) Render blocks with AnimatedStreamingMarkdown

AnimatedStreamingMarkdown(
  blocks: appendResult.blocks,
  asSliver: true,
  tokenStaggerDelay: const Duration(milliseconds: 180),
  tokenAnimationDuration: const Duration(milliseconds: 240),
  enableSelection: true,
  tokenAnimationBuilder: (
    BuildContext context,
    AnimatedMarkdownToken token,
  ) {
    final t = Curves.easeOutCubic.transform(token.value);
    return Transform.translate(
      offset: Offset(0, (1 - t) * 8),
      child: Opacity(opacity: t, child: token.child),
    );
  },
);

3) Render LaTeX math with KaTeX-compatible syntax

LaTeX is supported in both inline and display forms:

AnimatedStreamingMarkdown.fromMarkdown(
  markdown: r'''
Inline math: $x^2 + y^2 = z^2$

Display math:

$$
\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$
''',
);

Use latexBuilder to wrap or replace the default flutter_math_fork widget:

AnimatedStreamingMarkdown(
  blocks: appendResult.blocks,
  latexBuilder: (context, latex) {
    return latex.defaultWidget;
  },
);

4) Important APIs

  • MarkdownStreamParser.start()
  • MarkdownStreamParser.replace(markdown)
  • MarkdownStreamParser.append(chunk)
  • MarkdownStreamParser.parse(operation, text)
  • MarkdownStreamParser.dispose()
  • MarkdownSyncParser.parseMarkdown(markdown)
  • warmUpStreamingMarkdownParser(includeWorker: true)
  • AnimatedStreamingMarkdown(...)
  • AnimatedStreamingMarkdown.fromMarkdown(...)
    • blocks
    • asSliver
    • tokenStaggerDelay
    • tokenAnimationDuration / tokenAnimationDurationFactor
    • tokenAnimationBuilder
    • onTokenDelay
    • showCodeBlockCopyButton
    • enableSelection
    • blockBuilder
    • imageBuilder
    • latexBuilder

For a complete integration sample, check example/lib/src/demos/markdown_cases_demo.dart. For the full chatbot sample with Ollama, ChatGPT/OpenAI, Claude, Gemini, and Grok providers, check example/lib/main.dart.

Documentation

The documentation site is built with Docusaurus from docs/ and deployed to GitHub Pages by Deploy Documentation.

Run the docs site locally:

cd website
npm ci
npm run start

Build the static site:

cd website
npm run build

Migration notes for 0.3.0

0.3.0 keeps the 0.2.x API available, but the preferred names now describe the package behavior more directly:

0.2.x name 0.3.x preferred name
StreamingMarkdownParseWorker MarkdownStreamParser
request(op: 'set', ...) replace(markdown)
request(op: 'append', ...) append(chunk)
StreamingMarkdownParseResult.renderNodes MarkdownParseResult.blocks
StreamingMarkdownRenderView AnimatedStreamingMarkdown
nodes blocks
sliver asSliver
tokenArrivalDelay tokenStaggerDelay
tokenFadeInDuration tokenAnimationDuration
tokenFadeInRelativeToDelay tokenAnimationDurationFactor
allowUnclosedInlineDelimiters allowIncompleteInlineSyntax
enableTextSelection enableSelection
customBlockBuilder blockBuilder
markdownTheme theme

(back to top)

Roadmap

  • Done: Incremental parser worker (replace / append)
  • Done: Streaming renderer for markdown block nodes
  • Done: Per-token custom animation builder API
  • Done: Example with multiple animation presets
  • Done: Docusaurus documentation site for samnn.dev
  • Done: Convenience constructors and sync parser helpers
  • Done: Opt-in code block copy button
  • Done: KaTeX-compatible LaTeX math rendering
  • Planned: Richer copy modes and improved multi-content drag selection
  • Planned: More parser/renderer benchmark scenarios

See the open issues for proposed features and known issues.

(back to top)

Contributing

Contributions are welcome.

  1. Fork the project
  2. Create your branch (git checkout -b feature/your-feature)
  3. Commit your changes (git commit -m "Add your feature")
  4. Push branch (git push origin feature/your-feature)
  5. Open a Pull Request

See CONTRIBUTING.md for local setup, repository layout, and quality gates.

(back to top)

License

Distributed under the Apache-2.0 License. See LICENSE for details.

(back to top)

Contact

(back to top)

Acknowledgments

(back to top)

Libraries

animated_streaming_markdown
Animated streaming Markdown public API.