comrak
A 100% CommonMark and GitHub Flavored Markdown compatible parser and formatter for Rust, rendering to HTML, XML, or CommonMark.
Repository Health
Technical Analysis
Comrak is a Rust library and command-line tool that parses CommonMark and GitHub Flavored Markdown into a mutable AST, then renders it to HTML, XML, or back to CommonMark. It passes 100% of both the CommonMark and GFM conformance test suites, and it models cmark-gfm’s structure closely enough that bug-for-bug compatibility with GitHub’s own renderer is a design goal, not an accident.
Beyond spec compliance, Comrak ships a wide set of extensions unique to it or borrowed from GFM: tables, task lists, strikethrough, footnotes, math, wikilinks, alerts, description lists, front matter, and more, each toggled independently through an Options struct. Because parsing builds a real AST backed by typed_arena, callers can walk and mutate the tree before formatting, or plug in their own syntax-highlighting or output-formatting logic via SyntaxHighlighterAdapter and create_formatter!. It’s the Markdown engine behind crates.io, docs.rs, GitLab, and Deno’s deno_doc, and it has official or community bindings for Ruby, Elixir, Python, and TypeScript/WASM.
What You Get
- A parser that is 100% conformant with the CommonMark 0.31.2 and GitHub Flavored Markdown specs, verified against both official test suites in CI
- An
Arena-backed AST (comrak::nodes::AstNode) you can traverse and mutate before rendering, not just a one-shot string-to-string transform - Three output formatters out of the box: HTML, XML, and round-trip CommonMark, plus a
create_formatter!macro to override behavior for specific node types - A large catalog of independently-togglable extensions: tables, task lists, strikethrough, autolinks, footnotes, math, wikilinks, alerts, description lists, front matter, multi-line blockquotes, and more
- A pluggable syntax-highlighting interface (
SyntaxHighlighterAdapter) with a built-insyntectplugin for fenced code blocks - A standalone
comrakCLI binary for reformatting or converting Markdown files from the shell, install viacargo install comrak, Homebrew, pacman, dnf, or Scoop - Safe-by-default HTML output that scrubs raw HTML and dangerous links unless explicitly disabled with the
unsafeoption
Common Use Cases
- Rendering README and documentation Markdown to HTML in a Rust web service or static-site generator (as crates.io and docs.rs do)
- Building a GitHub-compatible Markdown preview or comment renderer that needs the exact GFM extension set (tables, tasklists, strikethrough)
- Programmatically rewriting Markdown content, such as link rewriting or text substitution, by walking and mutating the parsed AST before formatting
- Embedding syntax-highlighted code blocks in rendered documentation via the
syntectplugin adapter - Reformatting or linting CommonMark files in place from the command line using the bundled
comrakbinary - Powering Markdown rendering in non-Rust languages through community bindings (Ruby’s Commonmarker, Elixir’s MDEx, Python’s comrak/comrak-ext, or WASM/TypeScript)
Under The Hood
Architecture
Comrak’s core is an arena-allocated DOM-like tree (src/arena_tree.rs, adapted from rust-forest) that backs the public AstNode type re-exported from src/nodes.rs; every parsed document lives in a typed_arena::Arena and nodes reference each other via Cell<Option<&Node>> parent/sibling/child pointers, trading idiomatic ownership for cheap mutation and traversal. Parsing itself (src/parser/mod.rs plus src/parser/inlines/, src/parser/table.rs, src/parser/autolink.rs, src/parser/shortcodes.rs) closely mirrors cmark-gfm’s two-phase block/inline design: a block-level pass builds the tree structure, then a second inline pass resolves emphasis, links, and extension syntax within each block’s text. Formatting is symmetric to parsing, with dedicated modules for HTML (src/html.rs, src/html/context.rs), CommonMark round-tripping (src/cm.rs), and XML, each consuming the same AST so new output formats plug in without touching the parser. The create_formatter! macro and SyntaxHighlighterAdapter trait (src/adapters.rs, src/plugins/) are the two documented extension points, letting callers override rendering per node type or supply a custom code-highlighting backend without forking the crate.
Tech Stack
Comrak targets Rust 1.85+ (edition 2024) and depends on typed-arena for its AST allocator, phf/phf_codegen for compile-time-generated lookup tables (entity references, character classes), rustc-hash and smallvec for hot-path performance, and finl_unicode plus caseless for Unicode-aware classification. The CLI binary is feature-gated behind cli and pulls in clap for argument parsing, xdg for config-file discovery, and optional shell-words/fmt2io support; syntax highlighting is an optional syntect feature with separate syntect-onig (C Oniguruma) and syntect-fancy (pure-Rust regex) backends to avoid symbol collisions on hosts like Ruby-on-Windows. A build.rs script pre-generates entity and character-set tables at compile time via entities and phf_codegen rather than parsing them at runtime.
Code Quality
The test suite is extensive and spec-driven: src/tests/ contains well over 500 #[test] functions organized one file per extension (alerts, footnotes, math, tables, wikilinks, and so on), plus dedicated pathological.rs and fuzz.rs suites for adversarial inputs, and commonmark.rs/html.rs files that replay the official CommonMark and GFM spec fixtures directly. CI (.github/workflows/rust.yml) runs the full suite across nightly, beta, stable, and the pinned MSRV toolchain, separately builds and runs the CLI binary’s spec conformance script, and builds a WASM target; there are additional workflows for continuous fuzzing (fuzz.yml), performance regression tracking via Codspeed (codspeed.yml), and static analysis via Semgrep (semgrep.yml). The crate denies missing_docs and missing_debug_implementations at the lint level, and the project publishes an explicit policy against LLM-generated contributions.
What Makes It Unique
Comrak’s defining trait is exhaustive spec conformance combined with AST-level extensibility: it claims and CI-verifies 100% pass rates on both the CommonMark and GFM test suites (badges in the README track this per-release), which is a higher bar than most Rust Markdown crates target. Unlike event-stream parsers such as pulldown-cmark, Comrak always materializes a full mutable tree, which is what makes programmatic Markdown rewriting (used by its own maintainer to generate a GitHub profile README) practical without a second parse pass. Its safe-by-default posture, scrubbing raw HTML and dangerous links unless unsafe is explicitly opted into, predates and likely influenced similar defaults adopted elsewhere in the Markdown-renderer ecosystem, and its adoption by crates.io, docs.rs, GitLab, and Deno gives its GFM-compatibility claims unusually strong real-world validation.