Unified & Plugin Ecosystem Integration
Last Updated April 4, 2026
The @toaq-oss/omni-mdx parser is entirely written in Rust for maximum performance, but it doesn’t operate in an isolated bubble. We provide a seamless, zero-config bridge to the unified ecosystem, allowing you to use hundreds of existing community plugins.
Why Ecosystem Compatibility Matters
The MDX and Markdown communities have spent years building incredible tools to transform content: syntax highlighters (rehype-highlight), heading anchor generators (rehype-slug), table of contents builders, and more.
Reinventing these tools in Rust would take years and lock users into a proprietary ecosystem. Instead, Omni-MDX offers the best of both worlds:
- The speed of Rust: The heavy lifting of parsing raw text into an Abstract Syntax Tree (AST) is done natively.
- The flexibility of JavaScript: The resulting AST is mapped to the standard
hast(HTML AST) format, allowing any existingrehypeplugin to modify it before it reaches React.
The Architecture: Rehype vs Remark
In the traditional unified ecosystem, there are two main steps:
- Remark: Parses Markdown into an
mdast(Markdown AST). - Rehype: Transforms the
mdastinto ahast(HTML AST).
Omni-MDX skips the Remark phase entirely. Because our Rust core directly generates HTML-equivalent nodes (e.g., <h1>, <div>, <pre>) to ensure the fastest possible React rendering, our AST translates directly to HAST.
rehype-* plugins with Omni-MDX, not remark-* plugins.Performance: The Hybrid Cost
While adding JavaScript plugins (rehype-highlight, etc.) introduces a small overhead due to the Rust-to-JS bridge, Omni-MDX remains significantly faster because the initial parsing (the heaviest task) is already completed natively. The JS engine only processes a pre-structured HAST tree instead of raw text.
Usage in Server Components (Async)
Injecting plugins into the Omni-MDX pipeline is as simple as passing an options object to parseMdx. Because many plugins perform asynchronous operations (like loading language grammars for syntax highlighting), this is the recommended approach.
Here is an example using rehype-highlight in a Next.js Server Component:
Usage in the Browser (Client-Side)
If you are building a live MDX editor, you can also use plugins directly in the browser via WebAssembly.
rehype plugins rely on Node.js native APIs (fs, path) and will crash your bundler (Webpack/Turbopack) if imported into a "use client" file.Synchronous Parsing
If you are in an environment where you cannot use await (e.g., a legacy synchronous data pipeline), you can use parseMdxSync.
Limitations of Sync:
The unified ecosystem is asynchronous by default. If you use parseMdxSync and provide a plugin that attempts to perform an asynchronous task (like reading a file or making a network request), the unified engine will throw an error: “Cannot call runSync on an async plugin”. Whenever possible, prefer the standard async parseMdx function.
Passing Options to Plugins
Omni-MDX accepts standard unified PluggableList types. This means you can pass configurations to your plugins using nested arrays, exactly as you would in standard MDX setups: