Comark vs markdown-it

Comark is built on markdown-exit, a TypeScript rewrite of markdown-it. Compare their output, plugin compatibility, defaults, streaming, and framework rendering.

TL;DR: markdown-it parses Markdown into a flat token stream and renders it to an HTML string. Comark parses with markdown-exit, a TypeScript rewrite of markdown-it that keeps its plugin API. Comark then converts the tokens into a tree document that renders natively in Vue, React, Svelte, and Angular, and to HTML and ANSI strings.

At a glance

Comarkmarkdown-it
Tokenizermarkdown-exit, a TypeScript rewrite of markdown-itmarkdown-it
OutputMarkdownDocument tree, then HTML, framework components, or ANSIHTML string from md.render(), flat tokens from md.parse()
Pluginsmarkdown-it parsing plugins, plus Comark pluginsmarkdown-it plugins with md.use() and the Ruler API
Renderer rulesIgnored, Comark has its own renderersmd.renderer.rules
Raw HTMLParsed into nodes by defaultOff by default (html: false)
LinkifyOn by defaultOff by default
Custom components in contentYes, ::alert{type="info"}No, only through plugins
Incomplete MarkdownautoClose completes the syntaxNo handling
APIAsyncSync only

Same tokenizer, different output

markdown-it has two steps. md.parse() returns a flat list of tokens, with _open and _close pairs. md.render() turns those tokens into an HTML string.

Comark replaces the second step. It converts the tokens into a tree of tuples, the document model:

import { parseMarkdown } from 'comark'

const document = await parseMarkdown('# Hello **World**')
// document.nodes:
// [['h1', { id: 'hello-world' }, 'Hello ', ['strong', {}, 'World']]]

The document is JSON-safe. You can cache it, send it to a client, and render it with <MarkdownDocument> in Vue or React. Framework renderers create real components, not an HTML string that you insert with innerHTML.

Bring your markdown-it plugins

Comark accepts markdown-it plugins through markdownItPlugins in a Comark plugin. They're registered on the underlying markdown-exit instance:

import MarkdownIt from 'markdown-it'
import markdownItSub from 'markdown-it-sub'

const md = new MarkdownIt().use(markdownItSub)
const html = md.render('H~2~O is water')

Plugins that add inline rules, block rules, or core rules work, such as subscript, containers, and abbreviations. Plugins that only change md.renderer.rules have no effect, because Comark doesn't use the markdown-it renderer. Map the tag to a component instead. See markdown-it plugins for details.

Use Comark syntax in markdown-it

The reverse also works. If a tool already owns a markdown-it instance, such as VitePress, you can add Comark component and attribute syntax to it:

import { markdownItComponents } from 'comark/plugins/components'
import { markdownItAttributes } from 'comark/plugins/attributes'

md.use(markdownItComponents)
md.use(markdownItAttributes)

See the components plugin and the VitePress example.

Defaults and security

markdown-it is safe by default. It disables raw HTML, and its validateLink rejects javascript:, vbscript:, file:, and non-image data: URLs.

Comark is open by default. Markdown link syntax with an unsafe URL doesn't become a link, but raw HTML is parsed into nodes and kept, including <script>. Attributes and component props are also kept as written. For untrusted input, add the security plugin with a blockedTags list, or set registerDefaultPlugins: false and register the plugins you need without html.

CommonMark differences

markdown-it follows the CommonMark spec. markdown-exit keeps that behavior, but Comark's conversion to its document model changes some output. For example, [foo] is a Comark span instead of a shortcut reference link, and tight and loose lists render the same way. autoClose is on by default, so *foo becomes emphasis. See Differences from CommonMark and GFM.

What markdown-it does well

  • Safe defaults: raw HTML is off and link validation is built in.
  • Plugin ecosystem: a very large number of plugins on npm. Comark can use the ones that add parsing rules.
  • Maturity and speed: markdown-it is a mature, fast parser that many tools build on, such as VitePress and Markstream.
  • Size: Comark adds a YAML parser, an HTML parser, and its own renderers, so it's larger.

If you need a synchronous HTML string from Markdown, markdown-it is the smaller tool.

FAQ

© 2026 Vercel, Inc.