Analysis

Streamdown Migration - Completed ✅

2026.02.1310 min read

Essa Mamdani

AI Engineer & Crypto Volatility Analyst

Date: 2026-02-14
Suggested By: Essa Mamdani
Status: Migrated from marked to streamdown


Why Streamdown?

Previous Setup (marked + dangerouslySetInnerHTML):

  • ❌ Server-side HTML string generation
  • ❌ Used dangerouslySetInnerHTML (security risk)
  • ❌ Manual regex hacks for Mermaid diagrams
  • ❌ No syntax highlighting out of the box
  • ❌ Not type-safe (HTML strings)

New Setup (Streamdown):

  • React-native markdown rendering (type-safe)
  • No dangerouslySetInnerHTML (safer)
  • Built-in plugins: Code highlighting (Shiki) + Mermaid
  • Static mode: Optimized for blog articles
  • Better Next.js integration (client component for content, server for metadata)
  • Drop-in replacement for react-markdown

Reference: https://streamdown.ai/docs/usage


Implementation

1. Installed Packages

bun add streamdown @streamdown/code @streamdown/mermaid

Installed:

Removed:

2. Created Client Component

File: components/article-content.tsx

'use client'

import { Streamdown } from 'streamdown'
import { code } from '@streamdown/code'
import { mermaid } from '@streamdown/mermaid'

export function ArticleContent({ content }: { content: string }) {
  return (
    <div className="prose prose-lg dark:prose-invert max-w-none">
      <Streamdown
        mode="static"  // Optimized for static content
        plugins={{
          code: code,      // Syntax highlighting
          mermaid: mermaid, // Diagrams
        }}
        shikiTheme={['github-light', 'github-dark']} // Theme per dark mode
        mermaid={{
          config: {
            theme: 'dark',
            themeVariables: {
              primaryColor: '#10b981',  // Emerald green
            },
          },
        }}
      >
        {content}
      </Streamdown>
    </div>
  )
}

3. Updated Article Page

Before:

// Server component - converted markdown to HTML string
const htmlContent = await marked.parse(article.content)

// Manual Mermaid regex hacks
htmlContent = htmlContent.replace(
  /<pre><code class="language-mermaid">...
)

// Unsafe HTML rendering
<article dangerouslySetInnerHTML={{ __html: htmlContent }} />

After:

// Server component - passes raw markdown to client
import { ArticleContent } from '@/components/article-content'

// Clean, safe rendering
<ArticleContent content={article.content} />

Architecture

Server vs Client Components

Server Component (app/articles/[slug]/page.tsx):

  • Handles metadata generation (generateMetadata)
  • Static params generation (generateStaticParams)
  • File system reads (via lib/markdown.ts)
  • SEO optimization

Client Component (components/article-content.tsx):

  • Renders markdown with Streamdown
  • Handles syntax highlighting
  • Interactive Mermaid diagrams
  • Progressive enhancement

Why This Split?

  • Server components can't use interactive features (React state, effects)
  • Streamdown uses client-side rendering for optimal streaming support
  • Metadata + data fetching stay fast (server-side)
  • Content rendering gets React benefits (client-side)

Features Enabled

1. Syntax Highlighting (Shiki)

Automatic code highlighting with dual themes:

const example = "Highlighted automatically!"

Supports:

  • 100+ languages
  • Light/dark theme switching
  • Line numbers
  • Diff highlighting

2. Mermaid Diagrams

Renders diagrams from markdown:

graph LR
    A[Start] --> B[Process]
    B --> C[End]

Supports:

  • Flowcharts, sequence diagrams, Gantt charts
  • Dark mode optimized
  • Custom themes

3. Markdown Extensions

  • GitHub Flavored Markdown (GFM)
  • Tables
  • Task lists
  • Strikethrough
  • Autolinks

Testing Checklist

After deployment:

  • Articles render correctly (no HTML string artifacts)
  • Syntax highlighting works (light/dark themes)
  • Mermaid diagrams render
  • No dangerouslySetInnerHTML warnings
  • Build succeeds (no type errors)
  • Performance (should be faster with static mode)

Future Enhancements

Optional Plugins (install if needed):

  1. Math Rendering:

    bun add @streamdown/math katex
    
  2. CJK Support:

    bun add @streamdown/cjk
    
  3. AI Streaming Mode:

    • Switch from mode="static" to default streaming
    • Use with Vercel AI SDK for real-time AI markdown generation

Performance Impact

Before (marked):

  • Server-side HTML generation
  • No code splitting
  • Manual script injection for Mermaid

After (Streamdown):

  • Client-side rendering (hydration)
  • Code-split plugins (on-demand loading)
  • Built-in optimization

Result: Slightly larger client bundle (+50KB for Shiki themes), but better developer experience, type safety, and maintainability.


Documentation


Next Steps:

  1. Monitor build logs → Should succeed without errors
  2. Test articles on production → Check syntax highlighting + Mermaid
  3. Optional: Add math rendering if needed (@streamdown/math)

Migration complete! 🚀

You May Also Like

What Is Crypto Volatility
7 Proven Volatility Trading Strategies
Cryptocurrency Volatility Comparison
FAQ
Market Analysis
All Blog Posts
LiveVolatile Home

Share This Article

Reactions

Comments (0)

Join Discussion

No comments yet. Be the first to react to today's CPI/PPI setup!