A markdown parser and renderer for egui.
Parses CommonMark markdown into a token stream, then renders it as a single interactive egui widget with selectable text, clickable links, syntax-highlighted code blocks, tables, images, blockquotes, lists, and more.
use eframe::egui;
use egui_markdown::MarkdownLabel;
fn show_markdown(ui: &mut egui::Ui) {
let text = "# Hello\n\nThis is **bold** and *italic*.";
MarkdownLabel::new(ui.id().with("md"), text).show(ui);
}CommonMark - headings (H1-H6), paragraphs, bold, italic, strikethrough, inline code, fenced code blocks, links, images, blockquotes (nested), ordered and unordered lists (nested), horizontal rules.
GitHub Flavored Markdown - tables (with column alignment), task lists, footnotes.
- Text selection - rendered markdown is selectable just like normal egui text.
- Scrollable code blocks - long lines scroll horizontally instead of wrapping.
- Code block overlays - attach buttons (copy, language badge, etc.) to code blocks via a callback.
- Syntax highlighting -
syntect-based highlighting with built-in base16-ocean dark/light themes and support for custom themes. - Custom link handlers - the
LinkHandlertrait lets you style links, handle clicks, render links as inline widgets or full block-level widgets, and override layout. - Streaming / heal mode -
.heal(true)auto-closes unclosed code fences, bold, italic, links, and tables so partially-received LLM output renders correctly. - Configurable style -
MarkdownStylecontrols inline code colors, code block padding/radius/stroke, code font size, heading scales, horizontal rule stroke, blockquote indent, and block spacing. Includes a built-in interactive editor viaMarkdownStyle::ui(). - Bold font family - uses a registered
"bold"font family when available, falling back to strong text color. - Layout caching + viewport culling - hash-based layout caching with per-segment viewport culling for smooth scrolling through large documents.
| Feature | Default | Description |
|---|---|---|
syntax_highlighting |
Yes | Syntax-highlighted code blocks via syntect. |
images |
No | Render images inline via egui_extras image support. |
svg |
No | SVG image support via egui_extras. |
Control the visual appearance of all markdown elements via MarkdownStyle.
use egui_markdown::{MarkdownLabel, MarkdownStyle};
let mut style = MarkdownStyle::default();
style.heading.scales[0] = 2.0; // Bigger H1
style.code_font_size = 14.0;
MarkdownLabel::new(id, text).style(&style).show(ui);MarkdownStyle also provides a ui() method that renders an interactive editor
for all style fields - see the advanced example.
Implement the LinkHandler trait
to customize link styling, click handling, and rendering. Links can be rendered as
inline widgets (e.g. user mentions, status badges) or block-level widgets (e.g. embeds,
cards) by implementing inline_widget() / is_block_widget().
Pass a custom syntect::highlighting::Theme via .code_theme() to override the
built-in base16-ocean theme.
Enable .heal(true) on MarkdownLabel to auto-close unclosed code fences and inline
constructs before parsing. This prevents partial markdown from swallowing subsequent
text - useful for streaming LLM output.
| Example | Description |
|---|---|
simple |
Editor + rendered output. |
advanced |
Style editor, custom link handlers, inline widgets, code block buttons, streaming simulation. |
cargo run --example simple
cargo run --example advancedMIT or Apache-2.0