Rendering

ANSI Terminal Rendering

Render Comark content as styled terminal output using ANSI escape codes — perfect for CLIs, scripts, and developer tooling.

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)

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)

Options

OptionTypeDefaultDescription
colorsbooleantrue*Emit ANSI escape codes
widthnumber80Terminal width for HR and code block headers
componentsRecord<string, fn>{}Custom component renderers
dataRecord<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

Copyright © 2026