Markdown

free

Markdown renders streamed or static text as themed, incomplete-safe markdown with built-in code highlighting.

streamdown
Preview
Dark

Deployment summary

Three services updated cleanly and no errors were reported.

  • auth-service — 2m 14s
  • billing-service — 1m 48s
  • notifications-service — 57s

See the full log [blocked] for details.

import { Markdown } from '@/components/composites/Markdown';

const content = `## Deployment summary

Three services updated cleanly and no errors were reported.

- \`auth-service\` — 2m 14s
- \`billing-service\` — 1m 48s
- \`notifications-service\` — 57s

See the [full log](#) for details.`;

export default function UsageDemo() {
  return <Markdown>{content}</Markdown>;
}

Installation

Add this component with the NateUI CLI.

npx nateui@latest add Markdown

Examples

Code Block

Fenced code renders through streamdown's own built-in highlighter — a light/dark-aware theme and a copy button, with no extra wiring required.

Preview
Dark

Here is a small helper:

import { Markdown } from '@/components/composites/Markdown';

const content = `Here is a small helper:

\`\`\`ts
function clamp(value: number, min: number, max: number): number {
  return Math.min(Math.max(value, min), max)
}
\`\`\`
`;

export default function CodeBlockDemo() {
  return <Markdown>{content}</Markdown>;
}

Table

Tables get a minimal bordered treatment with a horizontal-scroll wrapper for narrow containers.

Preview
Dark
ServiceStatusLatency
auth-serviceHealthy42ms
billing-serviceHealthy58ms
notifications-serviceDegraded210ms
import { Markdown } from '@/components/composites/Markdown';

const content = `| Service | Status | Latency |
| --- | --- | --- |
| auth-service | Healthy | 42ms |
| billing-service | Healthy | 58ms |
| notifications-service | Degraded | 210ms |`;

export default function TableDemo() {
  return <Markdown>{content}</Markdown>;
}

Streaming

streamdown tolerates unclosed markdown syntax mid-stream — the same content, revealed a few characters at a time, never flashes broken formatting while it arrives.

Preview
Dark
import { useEffect, useState } from 'react';
import { Markdown } from '@/components/composites/Markdown';

const fullText = `**Streaming a reply:**

This paragraph is being revealed a few characters at a time, and the bold text above stayed intact the whole way through — even while its closing \`**\` had not arrived yet.`;

export default function StreamingDemo() {
  const [length, setLength] = useState(0);

  useEffect(() => {
    if (length >= fullText.length) return;
    const id = setTimeout(() => setLength((current) => current + 3), 30);
    return () => clearTimeout(id);
  }, [length]);

  return <Markdown>{fullText.slice(0, length)}</Markdown>;
}

API

Markdown

PropDescriptionTypeDefault
childrenThe markdown source to render.string
classNameClasses merged with the rendered root.string