Skip to content

Angular streaming Markdown renderer for AI chat

markstream-angular provides an Angular 20+ standalone component for streamed Markdown surfaces such as AI chat, SSE output, WebSocket output, incomplete Markdown states, long documents, Mermaid, KaTeX, and streaming code blocks. It is currently the alpha renderer in the Markstream family, so evaluate it against your production requirements before rollout.

When to use markstream-angular

Use markstream-angular when:

  • Content streams from an LLM, SSE, or WebSocket into an Angular standalone app
  • You want to pass an accumulating content string while the response is still streaming
  • You need progressive Mermaid diagrams in Angular
  • KaTeX math rendering during streaming matters
  • You need safe HTML rendering in Angular without [innerHTML]
  • Long AI responses need virtualized rendering

Quick Start

bash
pnpm add markstream-angular
ts
import { Component, signal } from '@angular/core'
import { bootstrapApplication } from '@angular/platform-browser'
import { MarkstreamAngularComponent } from 'markstream-angular'
import 'markstream-angular/index.css'

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [MarkstreamAngularComponent],
  template: `
    <markstream-angular
      [content]="markdown()"
      [final]="true"
    />
  `,
})
class AppComponent {
  readonly markdown = signal(`# Hello Angular

This is **markstream-angular**.`)
}

bootstrapApplication(AppComponent)

Streaming SSE example

ts
import { Component, signal } from '@angular/core'
import { MarkstreamAngularComponent } from 'markstream-angular'

@Component({
  selector: 'chat-message',
  standalone: true,
  imports: [MarkstreamAngularComponent],
  template: `
    <markstream-angular
      [content]="content()"
      [final]="final()"
      [fade]="false"
    />
  `,
})
export class ChatMessageComponent {
  readonly content = signal('')
  readonly final = signal(false)
}

Optional peers and what they enable

PeerEnables
mermaidMermaid diagrams
katexInline and block math rendering
stream-monacoMonaco-powered code blocks
@terrastruct/d2D2 diagrams
@antv/infographicInfographic blocks

Shiki is not documented for markstream-angular unless you add a supported integration path.

When not to use this package

  • You are below Angular 20
  • You only render short static Markdown and do not need streaming mid-state handling
  • You need a fully stable API surface today
  • You only want to render completed Markdown after an SSE stream finishes

For completed-document Markdown in mature enterprise apps, evaluate your existing Angular Markdown stack first. markstream-angular is for teams that specifically need live Markdown rendering while the model response is still incomplete.

Known limitations / maturity

  • Standalone component: no NgModule required
  • Signal-based: works with Angular signals for reactive content
  • OnPush renderer: implemented with ChangeDetectionStrategy.OnPush
  • Safe HTML: no [innerHTML] needed
  • Progressive Mermaid: diagrams render incrementally
  • KaTeX math: with worker support
  • Streaming code blocks: with diff tracking
  • Optional peers: install only what you need
  • Alpha status: check npm and the Angular guide for the latest API maturity

Try it

FAQ

Does markstream-angular require Angular 20?

Yes. The package targets Angular 20+ standalone components.

Is markstream-angular stable?

No. markstream-angular is currently alpha, so check the package documentation before using it in production.

Should I use markstream-angular instead of ngx-markdown?

Use markstream-angular when you specifically need Angular streaming Markdown mid-state rendering. For short static or completed Markdown, a mature completed-document renderer may be a better fit.

Do I need to pre-parse nodes for Angular SSE output?

No. Start by passing the accumulating content string and final state. Use nodes only when another layer already owns parsing or AST transforms.

Does markstream-angular use innerHTML for Markdown output?

The renderer is component-based and is designed to avoid dumping untrusted Markdown as raw innerHTML.