MdBin 레벨업: Custom Markdown 파이프라인에서 Streamdown으로
Source: Dev.to
위 링크에 포함된 본문을 번역하려면 해당 텍스트를 제공해 주세요. 텍스트를 주시면 요청하신 대로 한국어로 번역해 드리겠습니다.
Source: …
기존 설정: 작동했지만
내 원래 구현은 견고했습니다. 구문 강조를 위해 markdown-it-async와 @shikijs/markdown-it을 사용했습니다:
import { fromAsyncCodeToHtml } from '@shikijs/markdown-it/async'
import MarkdownItAsync from 'markdown-it-async'
import { codeToHtml } from 'shiki'
const md = MarkdownItAsync({
html: true,
xhtmlOut: true,
linkify: true,
typographer: true,
breaks: true,
})
md.use(
fromAsyncCodeToHtml(codeToHtml, {
themes: {
light: 'github-light',
dark: 'github-dark',
},
defaultColor: false,
cssVariablePrefix: '--shiki-',
})
)
export async function renderMarkdown(content: string): Promise {
const html = await md.renderAsync(content)
return html
}
그 다음 페이지 컴포넌트에서 클래식한 dangerouslySetInnerHTML을 사용해 결과를 렌더링했습니다:
단점
- 수동 보안 처리 —
dangerouslySetInnerHTML은 이름 그대로 위험합니다. - 내장된 제어 기능 부재 — 복사 버튼, 다운로드 기능 등을 직접 구현해야 했습니다.
- Mermaid는 악몽 — SSR 렌더링이 신뢰성 있게 동작하지 않았습니다.
- 번들 크기 증가 — 언어마다 하이라이트를 추가할수록 무게가 늘어났습니다.
- 불완전한 블록 처리 — 형식이 잘못된 마크다운이 전체 렌더링을 깨뜨릴 수 있었습니다.
Streamdown 소개
제가 Streamdown을 발견했을 때, 처음엔 무시했습니다. “AI 스트리밍용이겠지”라고 생각했죠. “MdBin은 정적 콘텐츠를 SSR로 렌더링한다.”
하지만 기능 세트를 자세히 살펴보니:
- 🎯 코드 구문 강조 with Shiki (이미 사용하고 있던 것)
- 📈 Mermaid 다이어그램 that actually work SSR
- 🛡️ 보안‑우선 with
rehype-harden - 📊 GitHub‑스타일 마크다운 out of the box
- 🔢 수학 렌더링 via KaTeX
- ⚡ 복사, 다운로드, 전체 화면을 위한 built‑in controls
바로 이것이 마크다운‑공유 도구에 필요한 전부입니다.
마이그레이션: 놀라울 정도로 간단함
새 구현이 어떻게 생겼는지 보세요:
import { Streamdown } from 'streamdown'
export default async function PastePage({ params }) {
const { id } = await params
const { decompressedContent, createdAt } = await cachedGetPaste(id)
return (
<Streamdown mode="static">
{decompressedContent}
</Streamdown>
)
}
그게 전부입니다. 별도의 렌더 함수도 없고, dangerouslySetInnerHTML도 없으며, 수동 보안 정화도 필요 없습니다.
Tailwind 설정은 globals.css에 한 줄만 추가하면 됩니다:
@source "../../node_modules/streamdown/dist/index.js";
왜 v2.0.0이 게임 체인저인가
타이밍이 이보다 좋을 수 없었습니다. Streamdown이 방금 v2.0.0을 출시했으며 대규모 개선이 포함되었습니다:
🚀 CDN을 통한 98 % 번들 크기 감소
이전에는 모든 Shiki 언어 문법과 테마를 번들링하면서 빌드가 부풀어졌습니다. 이제 언어별 하이라이팅과 KaTeX CSS가 CDN에서 필요할 때마다 로드됩니다. 빌드는 가볍게 유지되고, 사용자는 필요한 것만 가져갑니다.
📈 Mermaid SSR이 실제로 작동합니다
마크다운의 Mermaid 다이어그램은 흐름도, 시퀀스 다이어그램, 아키텍처 문서 등 매우 유용합니다—하지만 SSR 렌더링이 깨져 있었습니다. 이제는 아름답게 작동하며, 뷰포트 기반 지연 로딩을 통해 다이어그램이 여러 개 있을 때 페이지가 멈추는 것을 방지합니다.
🛡️ 강화된 보안
rehype-harden + rehype-sanitize 덕분에 악성 마크다운으로 인한 XSS 공격을 걱정할 필요가 없습니다. 컴포넌트가 자동으로 정화를 처리합니다.
✨ 내장된 UX 다듬기
직접 구현해야 했던 모든 컨트롤? 이제 내장되었습니다:
- 코드 블록 – 복사 버튼, 언어 표시
- 표 – CSV로 다운로드
- Mermaid – PNG로 다운로드, SVG 복사, 팬/줌이 가능한 전체 화면 보기
내가 얻은 것
| 기능 | 전 | 후 |
|---|---|---|
| 보안 | dangerouslySetInnerHTML 사용 수동 | 내장 rehype-harden |
| 코드 복사 | 맞춤 CopyButton 컴포넌트 | ✅ 내장 |
| Mermaid SSR | ❌ 깨짐 | ✅ 작동 |
| 표 다운로드 | ❌ 구현되지 않음 | ✅ 내장 |
| 수식 렌더링 | ❌ 구현되지 않음 | ✅ KaTeX 내장 |
| 번들 크기 | 언어마다 증가 | 필요 시 CDN 로드 |
| 불완전한 마크다운 | 렌더링을 깨뜨릴 수 있음 | 우아한 처리 |
“스트리밍” 부분
당신은 “정적 콘텐츠에 스트리밍 최적화 컴포넌트를 왜 사용하나요?” 라고 궁금할 수 있습니다. 답은 간단합니다—Streamdown의 스트리밍 모드는 점진적인 렌더링을 제공하기 때문입니다. 마크다운이 파싱되어 도착하는 대로 DOM에 스트리밍되므로 다음과 같은 이점이 있습니다:
- 첫 번째 의미 있는 콘텐츠가 표시되는 시간(Time‑to‑First‑Contentful‑Paint)이 빨라집니다(특히 큰 포스트의 경우).
- 무거운 다이어그램이나 코드 블록이 처리되는 동안 UI가 계속 반응합니다.
- 정적 SSR과 실시간 AI‑생성 스트림 모두에 동일하게 적용되어 향후 기능에 대한 유연성을 제공합니다.
요약하면, 더 깔끔한 코드베이스, 향상된 보안, 현저히 작은 번들, 그리고 풍부한 사용자 경험을 거의 마이그레이션 노력 없이 얻을 수 있었습니다.

“정적 콘텐츠용 ed 라이브러리?”
공정한 질문입니다. mode="streaming" 와 isAnimating={false} 프롭은 Streamdown에게 이것이 사전 렌더링된 콘텐츠임을 알려줍니다—타이핑 효과도 없고, 점진적 표시도 없습니다. 하지만 다른 모든 이점은 그대로 적용됩니다:
parseIncompleteMarkdown– 사용자가 잘못된 마크다운(닫히지 않은 코드 블록, 불완전한 테이블 등)을 붙여넣을 때 발생하는 예외 상황을 처리합니다. 충돌하거나 잡다한 내용이 표시되는 대신, 부드럽게 렌더링됩니다.- 메모이제이션된 렌더링 – 스트리밍이 없더라도, 성능 최적화가 재렌더링 시 도움이 됩니다.
Vercel 팀에게 감사 인사
Streamdown 팀은 복잡하고 여러 라이브러리를 조합해야 할 상황을 하나의 잘 설계된 컴포넌트로 깔끔하게 패키징하는 놀라운 작업을 해냈습니다. 이 컴포넌트는 그들의 AI Elements Message 컴포넌트를 구동하지만, 마크다운 렌더링이 필요한 모든 경우에 실제로 유용합니다.
- 문서가 탄탄합니다.
- 기본값이 합리적입니다.
- 그냥 바로 동작합니다.
직접 사용해 보기
위로 이동하여 마크다운을 붙여넣으세요. 시도해 보세요:
- 코드 블록을 모든 언어로—복사 버튼과 언어 배지를 확인하세요.
- Mermaid 다이어그램—이제 실제로 렌더링됩니다! 전체 화면 + 팬/줌을 시도해 보세요.
- 표—다운로드 버튼을 확인하세요.
- 수학 방정식—LaTeX가 바로 작동합니다.
붙여넣을 간단한 Mermaid 예시
graph TD
A[Paste Markdown] --> B[Streamdown Renders]
B --> C{What type?}
C -->|Code| D[Shiki Highlighting]
C -->|Diagram| E[Mermaid SVG]
C -->|Math| F[KaTeX Render]
D --> G[Beautiful Output]
E --> G
F --> G
- 전체 화면 모드 진입
- 전체 화면 모드 종료
다음 단계
렌더링 레이어가 이제 Streamdown으로 처리되면서, 사용자가 실제로 원하는 기능에 집중할 수 있게 되었습니다:
- 만료 옵션 – 1시간, 1일, 1주 또는 영구.
- 비밀번호 보호 – 민감한 콘텐츠용.
- 편집 링크 – 새로 만들지 않고 기존 붙여넣기를 업데이트.
- 맞춤 테마 – 라이트/다크 모드 외의 옵션.
기반은 견고합니다. 이제 구축할 차례입니다.
TL;DR: MdBin을 markdown-it + Shiki에서 Vercel의 Streamdown으로 마이그레이션했습니다. 내장 코드 복사, 실제 SSR에서 동작하는 Mermaid 렌더링, 수학 지원, 강화된 보안, 그리고 98 % 더 작은 번들 크기를 하나의 컴포넌트만으로 구현했습니다. Vercel 팀이 이 작업을 완벽히 해냈습니다.
업그레이드를 확인해 보세요 그리고 Streamdown repo.