NimblePublisher adapter for MDEx and Lumis, with support for both static Markdown rendering and Phoenix LiveView rendering.
- Syntax highlighting for 110+ languages powered by Tree-sitter via Lumis
- 120+ color themes from the Neovim ecosystem
- Automatic light/dark mode
- Static Markdown to HTML rendering
- Phoenix HEEx support when
:phoenix_live_viewis installed - Code block decorators
- GitHub Flavored Markdown via MDExGFM
- Extensible with more plugins — Mermaid diagrams, KaTeX math, Video, and more.
Getting Started
Pick the path that fits your situation:
- New project — start from scratch with Phoenix + blog
- Add a blog to an existing Phoenix project — scaffold a blog into your app
- Switch from Earmark to MDEx — already using NimblePublisher
New project
Install the Igniter archive if you haven't already:
mix archive.install hex igniter_new
Create a new Phoenix project with a blog already set up:
mix igniter.new my_blog --install nimble_publisher_mdex --with phx.new --with-args="--no-ecto"
This will generate a Phoenix app, add the dependency, and scaffold a blog module, sample post, and LiveView.
Add a blog to an existing Phoenix project
Run the installer to scaffold everything:
mix igniter.install nimble_publisher_mdex
This will add the dependency and generate a blog module, sample post, and LiveView. Then add the color-scheme meta tag to your root layout:
<meta name="color-scheme" content="light dark">Switch from Earmark to MDEx
Add the dependency:
def deps do
[
{:nimble_publisher_mdex, "~> 0.1"}
]
endSet the converter in your blog module:
use NimblePublisher,
build: __MODULE__,
from: "priv/posts/**/*.md",
as: :posts,
html_converter: NimblePublisherMDExRemove the :highlighters option and any makeup_* dependencies — MDEx handles syntax highlighting out of the box.
Add the color-scheme meta tag to your root layout:
<meta name="color-scheme" content="light dark">Configuration
Pass :mdex_opts to customize MDEx Options
Built-in defaults include:
[
plugins: [MDExGFM],
extension: [phoenix_heex: true],
render: [
unsafe: true,
github_pre_lang: true,
full_info_string: true
],
syntax_highlight: [
formatter:
{:html_multi_themes,
themes: [light: "github_light", dark: "github_dark"], default_theme: "light-dark()"}
]
]Static Markdown rendering works out of the box. If you also want MDEx to render Phoenix HEEx through LiveView, install the optional :phoenix_live_view dependency.
You can change the default options in the app config:
# config/config.exs
config :nimble_publisher_mdex,
mdex_opts: [
syntax_highlight: [
formatter: {:html_inline, theme: "dracula"}
]
]Or pass options directly through NimblePublisher:
use NimblePublisher,
build: __MODULE__,
from: "priv/posts/**/*.md",
as: :posts,
html_converter: NimblePublisherMDEx,
mdex_opts: [syntax_highlight: nil]Themes
Browse all available themes at lumis.sh. Some popular choices:
| Theme | Style |
|---|---|
github_light / github_dark | GitHub (default) |
catppuccin_latte / catppuccin_mocha | Catppuccin |
tokyonight_day / tokyonight_storm | Tokyo Night |
onedark | One Dark |
dracula | Dracula |
Summary
Functions
Converts a Markdown file to HTML using MDEx.
Implements the html_converter interface expected by
NimblePublisher.
Uses MDExGFM for GitHub Flavored Markdown (tables, strikethrough, autolinks, task lists, footnotes, alerts).
See more plugins for additional features like Mermaid diagrams, KaTeX math, and more.
Arguments
filepath- the path to the source filebody- the raw Markdown content (after frontmatter has been extracted)attrs- the parsed frontmatter attributes (unused)opts- options fromuse NimblePublisher
Configuration
MDEx options are resolved in the following order (later values win):
- Built-in defaults (unsafe HTML, Phoenix HEEx, code block decorators, light/dark syntax highlighting)
- Application config:
config :nimble_publisher_mdex, mdex_opts: [...] :mdex_optskey passed through the NimblePublisher opts
Examples
# Minimal — just set the converter
use NimblePublisher,
build: __MODULE__,
from: "priv/posts/**/*.md",
as: :posts,
html_converter: NimblePublisherMDEx
# Override via application config
config :nimble_publisher_mdex,
mdex_opts: [
syntax_highlight: [formatter: {:html_inline, theme: "dracula"}]
]
# Override via NimblePublisher opts
use NimblePublisher,
build: __MODULE__,
from: "priv/posts/**/*.md",
as: :posts,
html_converter: NimblePublisherMDEx,
mdex_opts: [syntax_highlight: nil]