Problem Statement
When streaming markdown, streamdown currently removes incomplete images (e.g.  instead of rendering a placeholder. This works fine for final output, but in streaming UIs it introduces a noticeable delay: nothing is shown until the full image URL is emitted and the markdown becomes valid. In contrast, links are handled more gracefully: incomplete links are replaced with a placeholder URL (streamdown:incomplete-link), so the user can already see the link text while the model is still streaming.
For image-heavy content, this behavior makes the streaming experience feel less responsive compared to how links are handled.
Proposed Solution
Introduce a streaming-friendly image handling mode, similar to incomplete link handling. For example:
-
When an image is incomplete (unterminated URL or closing ) missing), render a placeholder image or a “loading” image state instead of dropping the node.
-
Optionally provide a configurable placeholder strategy (e.g. built-in default, custom React component, or callback).
-
Once the full image URL has been streamed, update the rendered node in place to the real image.
The goal is that the user can see that “an image is coming” immediately, even before the markdown for the image is fully complete.
Alternatives Considered
-
Keeping the current behavior and waiting until the full image URL is streamed. This keeps the implementation simple but gives a worse UX for streaming, especially when models emit long or slow URLs.
-
Post-processing the model output on the host side to inject a custom placeholder when  instead of rendering a placeholder. This works fine for final output, but in streaming UIs it introduces a noticeable delay: nothing is shown until the full image URL is emitted and the markdown becomes valid. In contrast, links are handled more gracefully: incomplete links are replaced with a placeholder URL (streamdown:incomplete-link), so the user can already see the link text while the model is still streaming.For image-heavy content, this behavior makes the streaming experience feel less responsive compared to how links are handled.
Proposed Solution
Introduce a streaming-friendly image handling mode, similar to incomplete link handling. For example:
When an image is incomplete (unterminated URL or closing
)missing), render a placeholder image or a “loading” image state instead of dropping the node.Optionally provide a configurable placeholder strategy (e.g. built-in default, custom React component, or callback).
Once the full image URL has been streamed, update the rendered node in place to the real image.
The goal is that the user can see that “an image is coming” immediately, even before the markdown for the image is fully complete.
Alternatives Considered
Keeping the current behavior and waiting until the full image URL is streamed. This keeps the implementation simple but gives a worse UX for streaming, especially when models emit long or slow URLs.
Post-processing the model output on the host side to inject a custom placeholder when
![is detected without a closing ). This is possible but reimplements logic that streamdown(and remend) already understand, and is easy to get wrong for edge cases.Using text-only placeholders in the original markdown (e.g. “Loading image…”), then replacing them later. This requires changing prompts / model behavior and doesn’t leverage the existing markdown/image pipeline.
Use Case
Priority
Nice to have
Contribution
Additional Context
No response