ANSI Terminal Rendering
The @comark/ansi package renders Comark AST to ANSI-styled strings for terminal output. Install it separately:
npm install @comark/ansi
render(markdown, options?)
The quickest way to parse markdown and get an ANSI-styled string:
import { render } from '@comark/ansi'
const output = await render(`
# Getting Started
This is a **bold** statement with a [link](https://example.com).
- Item 1
- Item 2
`)
process.stdout.write(output)
# Getting Started ← bold + underline
This is a bold statement with a link (https://example.com).
• Item 1
• Item 2
ANSI colors are enabled by default and automatically disabled when the NO_COLOR environment variable is set.
createRender(options?)
Creates a reusable parse+render function. The underlying parser is initialized once and reused on every call — more efficient when rendering many documents.
import { createRender } from '@comark/ansi'
import math, { Math } from '@comark/ansi/plugins/math'
import highlight from '@comark/ansi/plugins/highlight'
const render = createRender({
plugins: [math(), highlight()],
components: { Math },
width: 120,
})
// Reuse the same configured parser
const out1 = await render('# Document 1\n\n...')
const out2 = await render('# Document 2\n\n...')
With Custom Components
import { createRender } from '@comark/ansi'
const render = createRender({
components: {
badge: ([, attrs, ...children], { render }) => {
return `[${String(attrs.type).toUpperCase()}] ${render(children)}`
},
},
})
const output = await render(`
::badge{type="success"}
Build passed
::
`)
// → [SUCCESS] Build passed
renderANSI(tree, options?)
Render a pre-parsed Comark tree to an ANSI string. Use this when you already have a parsed tree and want to avoid re-parsing.
import { parse } from 'comark'
import { renderANSI } from '@comark/ansi'
const tree = await parse(`
# Getting Started
This is a **bold** statement with a [link](https://example.com).
- Item 1
- Item 2
`)
const output = renderANSI(tree)
process.stdout.write(output)
# Getting Started ← bold + underline
This is a bold statement with a link (https://example.com).
• Item 1
• Item 2
Options
| Option | Type | Default | Description |
|---|---|---|---|
colors | boolean | true* | Emit ANSI escape codes |
width | number | 80 | Terminal width for HR and code block headers |
components | Record<string, fn> | {} | Custom component renderers |
data | Record<string, any> | — | Data passed to component renderers |
*Automatically set to false when NO_COLOR env var is present.
log(markdown, options?)
Parse and print markdown directly to stdout in one call:
import { log } from '@comark/ansi'
await log(`
# Hello World
This is **bold**, _italic_, and \`inline code\`.
> [!NOTE]
> @comark/ansi renders GitHub-style alerts with color.
`)
Pass options to configure the parser, renderer, or output destination:
import { log } from '@comark/ansi'
import math, { Math } from '@comark/ansi/plugins/math'
await log('Inline $E = mc^2$', {
plugins: [math()],
components: { Math },
width: 100,
write: (s) => process.stderr.write(s),
})
createLog(options?)
Creates a reusable log function with pre-configured options. The underlying parser is initialized once and reused on every call — more efficient when logging many documents.
import { createLog } from '@comark/ansi'
import math, { Math } from '@comark/ansi/plugins/math'
import highlight from '@comark/ansi/plugins/highlight'
const log = createLog({
plugins: [math(), highlight()],
components: { Math },
width: 120,
})
// Reuse the same configured parser
await log('# Document 1\n\n...')
await log('# Document 2\n\n...')
Syntax Support
Headings
Headings are styled by level — bold + underline for h1, with distinct colors per level down to h6.
GitHub Alerts
Blockquotes with [!TYPE] markers render as colored alerts matching GitHub's style:
> [!NOTE]
> Informational message.
> [!TIP]
> Helpful suggestion.
> [!IMPORTANT]
> Crucial information.
> [!WARNING]
> Potential risk.
> [!CAUTION]
> Danger ahead.
Each type has its own color: NOTE → blue, TIP → green, IMPORTANT → magenta, WARNING → yellow, CAUTION → red.
Code Blocks
Code blocks show the language and filename in a header line. When the highlight plugin is used, tokens are rendered with true-color ANSI (\x1b[38;2;R;G;Bm) derived from Shiki's dark theme:
import { createLog } from '@comark/ansi'
import highlight from '@comark/ansi/plugins/highlight'
const log = createLog({ plugins: [highlight()] })
await log('```typescript [app.ts]\nconsole.log("hello")\n```')
// typescript app.ts
// console.log("hello") ← syntax highlighted
Math
Math expressions from the math plugin render as colored LaTeX source — inline in yellow, block in magenta:
import { createLog } from '@comark/ansi'
import math, { Math } from '@comark/ansi/plugins/math'
const log = createLog({ plugins: [math()], components: { Math } })
await log('Inline $E = mc^2$ and block:\n\n$$\n\\frac{a}{b}\n$$')
Tables
Tables render with box-drawing characters:
┌─────────────┬─────────┐
│ Feature │ Status │
├─────────────┼─────────┤
│ Headings │ ✅ │
│ Code blocks │ ✅ │
└─────────────┴─────────┘
See Also
- HTML Rendering - Render to HTML strings
- Vue Renderer - Render with Vue components
- React Renderer - Render with React components
- API Reference - Full API reference