Knowledge Base

Migrating from MDX

How to convert MDX content to Comark syntax.

If you're coming from MDX, this guide maps every MDX concept to its Comark equivalent. The core idea is the same, embed components in Markdown — but Comark uses a text-friendly syntax instead of JSX.


Quick Comparison

ConceptMDXComark
Block component<Alert>...</Alert>::alert ... ::
Inline component<Badge>text</Badge>:badge[text]
Props<Alert type="info">::alert{type="info"}
Self-closing<Divider />::divider\n::
Dynamic bindingyear={year}:year="year"
ChildrenJSX childrenMarkdown between :: delimiters
Importsimport X from './X'Component registered in renderer
Exportsexport const x = 1Frontmatter or application state

Components

Block Components

MDX uses JSX tags. Comark uses :: fences:

<Alert type="info">
  This is an important message with **bold** text.
</Alert>

Inline Components

Status: <Badge color="green">Active</Badge>

Self-Closing Components

<Divider />
<Chart color="#fcb32c" />

Nested Components

<Card title="Example">
  <List>
    - Item 1
    - Item 2
  </List>
</Card>

Nesting in Comark uses increasing colons: :: for outer, ::: for inner, :::: for deeper levels.


Props & Attributes

Static Props

<Alert type="info" dismissible>
  Content
</Alert>

Dynamic / Expression Binding

MDX uses JSX curly-brace expressions. Comark uses :prop="value" binding syntax:

<Chart year={currentYear} data={chartData} />

The : prefix marks a prop as a dynamic binding — the value is treated as an expression rather than a literal string.

Numeric & Boolean Props

<Grid columns={3} fluid={true} />

Boolean props without a value default to true in both formats.


Imports & Component Registration

MDX imports components per-file. In Comark, components are registered once in the renderer:

import Alert from './components/Alert'
import Chart from './components/Chart'

# Dashboard

<Alert type="info">Welcome!</Alert>

<Chart data={metrics} />

For shared defaults, use defineComarkComponent to avoid passing components everywhere:

import { defineComarkComponent } from '@comark/vue' // or '@comark/react'
import Alert from './components/Alert'
import Chart from './components/Chart'

export const DocsComark = defineComarkComponent({
  name: 'DocsComark',
  components: { Alert, Chart },
})

Exports & State

MDX uses export statements to define page-level variables:

export const year = 2023

# Report for {year}

Comark doesn't support inline JavaScript expressions. Instead, use frontmatter for static metadata and application state for dynamic values:

---
year: 2023
---

# Report for {{ year }}

Expressions in Text

MDX allows JavaScript expressions anywhere in text:

The result is {2 + 3}.
Today is {new Date().toLocaleDateString()}.

Comark does not evaluate inline expressions. Compute values in your application code and interpolate them into the markdown string before parsing:

const result = 2 + 3
const today = new Date().toLocaleDateString()

const markdown = `
The result is ${result}.
Today is ${today}.
`

const tree = await parse(markdown)

Layouts

MDX supports layout components via default exports:

export { default } from './layouts/BlogPost'

# My Post

In Comark, wrap the renderer with your layout component:

<template>
  <BlogPostLayout>
    <Suspense>
      <Comark>{{ content }}</Comark>
    </Suspense>
  </BlogPostLayout>
</template>

Markdown Features

Standard markdown works identically in both formats. No changes needed for:

  • Headings, paragraphs, lists
  • Bold, italic, strikethrough
  • Links and images
  • Code blocks and inline code
  • Blockquotes
  • Tables
  • Horizontal rules

Migration Checklist

  1. Replace JSX tags with Comark ::component / :component syntax
  2. Move imports from per-file import statements to renderer components option
  3. Convert expression props prop={expr} to :prop="expr"
  4. Replace inline expressions {expr} with template string interpolation
  5. Move exports to frontmatter or application state
  6. Remove layout exports and wrap with layout components instead
  7. Register plugins (math, mermaid, highlight) in your renderer setup