Beautiful terminal markdown renderer with first-class streaming support.
Built for LLM/agent output — renders tokens as they arrive without ever showing broken markdown.
npm install streammarkPeer deps:
chalk@^5,string-width@^7
import { render, print } from 'streammark';
// Get ANSI string back
const ansi = render('# Hello\n\nThis is **streammark**', { theme: 'dracula' });
console.log(ansi);
// Or print directly
print('# Hello\n\nThis is **streammark**', { theme: 'nord' });import { MarkdownStream } from 'streammark';
const md = new MarkdownStream({ theme: 'dark' });
// Anthropic SDK
const stream = await anthropic.messages.stream({ ... });
for await (const chunk of stream) {
if (chunk.type === 'content_block_delta') {
md.write(chunk.delta.text);
}
}
md.end();
// OpenAI SDK
const stream = await openai.chat.completions.create({ stream: true, ... });
for await (const chunk of stream) {
md.write(chunk.choices[0]?.delta?.content ?? '');
}
md.end();| Theme | Description |
|---|---|
dark |
Default dark, high contrast |
dracula |
Dracula palette |
nord |
Nord palette |
light |
Clean light theme |
// Pass theme name
new MarkdownStream({ theme: 'dracula' });
// Or bring your own theme object
import { themes } from 'streammark';
const myTheme = { ...themes.dark, h1: { color: '#FF0000', bold: true } };
new MarkdownStream({ theme: myTheme });| Element | Behaviour |
|---|---|
| Headings, HR | Rendered immediately when line is complete |
| Paragraphs | Rendered line-by-line as newlines arrive |
| Code blocks | Buffered until closing ``` — then rendered with syntax highlighting |
| Tables | Buffered until table ends — then rendered with borders |
| Blockquotes | Buffered until block ends |
| Lists | Buffered until paragraph boundary |
Supported: js, ts, jsx, tsx, python, bash, sh, json, css
No external deps — built-in token-based highlighter.
Render a complete markdown string. Returns ANSI-styled string.
Render and write to stdout.
Streaming renderer.
opts.theme— theme name or object (default:'dark')opts.output— writable stream (default:process.stdout)
Feed a chunk (can be a single character/token).
Flush remaining content and finalize.
Convenience: pipe any async iterable of string chunks.