README.md

# PhoenixStreamdown

Streaming markdown renderer for Phoenix LiveView, optimized for LLM output.

Inspired by [Streamdown](https://streamdown.ai/) and [vue-stream-markdown](https://github.com/jinghaihan/vue-stream-markdown), but built to fully leverage LiveView — server-side rendering, automatic DOM diffing, and zero client-side JavaScript.

## Installation

```elixir
def deps do
  [{:phoenix_streamdown, "~> 1.0.0-beta"}]
end
```

## Usage

```elixir
use PhoenixStreamdown
```

```heex
<.markdown content={@response} streaming={@streaming?} />
```

That's it. Pass `content` as a markdown string, set `streaming` to `true` while tokens are arriving. Completed blocks are frozen with `phx-update="ignore"` — only the last block re-renders on each token.

## How it works

1. **Remend** — auto-closes incomplete syntax (`**bold` → `**bold**`, unclosed fences, partial links)
2. **Blocks** — splits into independent blocks so earlier ones are stable
3. **MDEx** — renders each block to HTML server-side (Rust-backed)
4. **LiveView** — diffs only the active block, skips the rest

On a 56-block document, this is **~7x less server work** and **~460x smaller diffs** per token compared to re-rendering the full document each time.

## Example

A full chat app with [ReqLLM](https://hex.pm/packages/req_llm) streaming is in the [`example/`](example/) directory. Run it:

```bash
cd example
cp .env.example .env  # add your OpenRouter API key
mix setup
mix phx.server
```

## Documentation

**[HexDocs](https://hexdocs.pm/phoenix_streamdown)** — attributes, customization (themes, CSS classes, stable IDs, MDEx options).

## License

MIT