Syntax highlighting

Copy Markdown View Source

Syntax highlighting is off by default and turned on with the :syntax_highlight option. Two engines are available:

With it off, fenced code blocks still render as code blocks with their content unchanged, and the language name goes on the <pre> class.

Lumis

Add Lumis to your deps, along with a parser for every language you highlight:

{:lumis, "~> 0.9"},
{:lumis_wasm_rust, "~> 0.26"},
{:lumis_wasm_elixir, "~> 0.26"}

The full list is at docs.lumis.sh/reference/languages.

Configure MDExNative before compiling dependencies:

config :mdex_native, syntax_highlighter: :lumis

Then pass syntax_highlight when rendering:

markdown = """
```rust
fn main() {
    println!("Hello from Lumis");
}
```
"""

html = MDExNative.Comrak.markdown_to_html(markdown,
  syntax_highlight: [
    engine: :lumis,
    opts: [
      formatter: {:html_inline, theme: "catppuccin_macchiato"}
    ]
  ]
)

Lumis formatters and options are documented in Lumis.

Parsers are dependencies

A parser is a WebAssembly module published as a lumis_wasm_* package. Nothing is compiled in and nothing is fetched at runtime: name a language you haven't installed and that fence comes out as plain text.

MDExNative reads those packages from the same place :lumis does and shares its cache of compiled parsers, so the VM pays for each one once.

Loading happens on first use, which costs a Wasmtime compile. Call Lumis.Languages.load/1 at startup to move most of that off the first request.

Syntect

Configure MDExNative before compiling dependencies:

config :mdex_native, syntax_highlighter: :syntect

Then pass a Syntect theme:

markdown = """
```rust
fn main() {
    println!("Hello from Syntect");
}
```
"""

html = MDExNative.Comrak.markdown_to_html(markdown,
  syntax_highlight: [
    engine: :syntect,
    opts: [theme: "Catppuccin Macchiato"]
  ]
)

Syntect theme names come from two-face.

Artifact size

Bundle size depends on the selected highlighter:

ConfigCompressed artifact size
syntax_highlighter: :lumis5 MB
syntax_highlighter: :syntect3 MB
syntax_highlighter: nil1 MB

Parsers are not in those numbers. They arrive as their own Hex packages, so you only download the languages you asked for.

Legacy CPUs

Modern CPU features are enabled by default. If your environment has an older CPU, use legacy artifacts:

config :mdex_native, use_legacy_artifacts: true