
I compared Marp and Reveal.js with the same content - Markdown slides vs HTML presentation
This page has been translated by machine translation. View original
Introduction
As methods for creating technical presentations, beyond PowerPoint and Google Slides, there are "code-based slide tools." Representative examples include Marp, which generates slides from Markdown, and Reveal.js, an HTML/JS-based presentation framework.
To determine which one suits my use case, I actually created the same content with both tools and compared them.
Prerequisites & Environment
- macOS (Apple Silicon)
- Node.js 22.x
- pnpm 11.x
- Marp CLI 4.4.0
- Reveal.js 5.1.0 (via CDN)
What is Marp?
Marp stands for "Markdown Presentation Ecosystem" — a tool that generates presentation slides from Markdown files.
Key features:
- Text written in Markdown becomes slides as-is
- Slides are separated by
---(horizontal rule) - CLI can convert to HTML / PDF / PPTX / PNG
- Live preview support via VS Code extension
- Themes and styles configured through front matter
What is Reveal.js?
Reveal.js is an HTML/CSS/JavaScript-based presentation framework. It also serves as the underlying technology for slides.com.
Key features:
- Fragment animations (display elements one at a time)
- Vertical slides (drill-down structure)
- Smooth transitions via
data-auto-animate - Code line highlighting via
data-line-numbers - Plugin ecosystem (math, notes, search, etc.)
Setup
Marp
Installing the VS Code extension marp-team.marp-vscode enables live preview of slides within the editor. Install the CLI as follows:
# Install CLI
pnpm add -D @marp-team/marp-cli
# Build slides
pnpm dlx @marp-team/marp-cli slides.md -o slides.html
# PDF output
pnpm dlx @marp-team/marp-cli slides.md -o slides.pdf
# PPTX output
pnpm dlx @marp-team/marp-cli slides.md -o slides.pptx
# Image output (for LinkedIn/Instagram carousels)
pnpm dlx @marp-team/marp-cli slides.md --images png
The output format is automatically determined by the file extension. PDF output requires Chrome/Chromium, but HTML/PPTX work without it.
Reveal.js
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/theme/black.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/plugin/highlight/monokai.css">
</head>
<body>
<div class="reveal">
<div class="slides">
<section>Slide 1</section>
<section>Slide 2</section>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.js"></script>
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/plugin/highlight/highlight.js"></script>
<script>
Reveal.initialize({
hash: true,
plugins: [RevealHighlight]
});
</script>
</body>
</html>
Via CDN, no installation is required and a single HTML file is all you need. For local installation, use pnpm add reveal.js.
Creating the Same Content in Both Tools
As test content, I turned a previously written article about "SSD write issues with AI coding CLI tools" into a presentation. It includes code blocks, tables, data comparisons, and a narrative flow — material that makes the strengths and weaknesses of both tools easy to see.
Marp Source Code (Excerpt)
---
marp: true
theme: default
paginate: true
backgroundColor: #1a1a2e
color: #eee
style: |
h1, h2, h3 { color: #e94560; }
th { background: #e94560; color: white; }
.columns { display: flex; gap: 2em; }
.columns > div { flex: 1; }
---
<!-- _class: lead -->
# AI Coding CLIs Are Killing Your SSD?
---
## The Incident
> OpenAI's Codex CLI was found writing **640TB/year** to SSDs
- Trace-level logging to `~/.codex/logs_2.sqlite`
- **37TB** written in just 21 days
---
## Why This Matters
<div class="columns">
<div>
### Consumer SSD Lifespan
| SSD | TBW Rating |
|-----|-----------|
| Samsung 990 PRO 1TB | ~600 TBW |
</div>
<div>
### Codex Impact
- **640 TB/year** write rate
- Exceeds warranty in **< 1 year**
</div>
</div>
Key points:
- CSS customization via the
style:block in front matter <!-- _class: lead -->applies the title slide layout- Two-column layout achieved with
<div class="columns">(HTML embedded within Markdown) - Tables, blockquotes, and code blocks all use standard Markdown
Reveal.js Source Code (Excerpt)
<!-- Fragment animation: elements appear one at a time -->
<section data-auto-animate>
<h2>Cross-Tool Comparison</h2>
<table>
<thead><tr><th>Tool</th><th>SSD Issue</th></tr></thead>
<tbody>
<tr class="fragment"><td>Codex CLI</td><td><span class="status-bad">Critical</span></td></tr>
<tr class="fragment"><td>Claude Code</td><td><span class="status-warn">Past issues</span></td></tr>
<tr class="fragment"><td>Gemini CLI</td><td><span class="status-ok">None</span></td></tr>
</tbody>
</table>
</section>
<!-- Vertical slides: drill down with the ↓ key -->
<section>
<section>
<h2>Claude Code: Past Bugs</h2>
<p><small>Press ↓ for each bug</small></p>
</section>
<section>
<h3>Bug 1: Debug Log Infinite Loop</h3>
<p class="fragment">Logger records ops taking >75ms</p>
<p class="fragment">→ Debug file grows large</p>
<p class="fragment">→ <span class="status-bad">42GB in 7 days</span></p>
</section>
</section>
<!-- Code line highlighting: focus area switches on each click -->
<section>
<pre><code class="language-bash" data-line-numbers="1-2|4-5|7-12">
$ du -sh ~/.claude/debug
2.8M ~/.claude/debug # Normal
$ du -sh ~/.claude/file-history
12M ~/.claude/file-history # Normal
$ du -sh ~/.claude/*/ | sort -hr | head -5
866M plugins/
434M projects/
266M security/
12M file-history/
2.8M debug/
</code></pre>
</section>
Key points:
class="fragment"displays elements one at a time with animation- Nested
<section>elements create vertical slides (drill-down) data-line-numbers="1-2|4-5|7-12"highlights code lines step by stepdata-auto-animateprovides smooth transitions between slidesdata-background-gradientchanges the background per slide
Comparison Results
Source Readability
Marp's source is Markdown that can be read as-is. Whether previewed on GitHub or opened in VS Code, the content is immediately understandable.
# Marp source: 244 lines of Markdown
$ wc -l slides.md
244
# Reveal.js source: 287 lines of HTML
$ wc -l index.html
287
The line counts look similar, but Reveal.js has many HTML tags like <section>, <div>, and <span>, meaning Marp's information density is overwhelmingly higher. Marp's source functions as documentation on its own, while Reveal.js source requires an HTML parser.
Animations & Transitions
This is the biggest difference.
Marp has no in-slide animation features. Slides simply transition at each ---. With Reveal.js, you get:
- Fragments: Display table rows one at a time, reveal conclusions gradually
- Vertical slides: Keep the main flow intact while showing details via drill-down
- Code line highlighting: Switch focus on each click with
data-line-numbers="1-2|4-5" - auto-animate: Elements move smoothly between slides
For technical videos (Fireship-style code walkthroughs) or conference talks, this difference is decisive.
Export
| Output Format | Marp | Reveal.js |
|---|---|---|
| HTML | Built-in | Built-in |
| Built-in (requires Chrome) | Requires separate tool (e.g. decktape) | |
| PPTX | Built-in | Not supported |
| PNG/JPG images | Built-in (--images) |
Not supported |
Marp's PPTX output is handy when you need to hand off files to colleagues who use PowerPoint. --images png can be used directly for social media carousel posts.
CI/CD Compatibility
Marp naturally lends itself to md → html/pdf/pptx CLI pipelines:
# Auto-build slides with GitHub Actions
pnpm dlx @marp-team/marp-cli slides.md -o dist/slides.html
Since Reveal.js is static HTML, no build step is needed, but automating PDF export requires a headless browser.
Themes and Styling
Marp allows scoped CSS via the style: block in front matter. While there are constraints, basic customization — colors, fonts, table styles, backgrounds — is fully achievable.
Reveal.js allows full CSS/JS, so there is no ceiling. Themes can be easily adjusted with CSS variables (like --r-heading-color), and complex layouts are completely free-form.
Choosing by Use Case
When Marp is the right fit
- Weekly meetings / sprint reviews: Quickly created in Markdown, Git-managed, diff-trackable
- Turning internal docs into slides: Just add
---to existing Markdown documents - LinkedIn / Instagram carousel posts: Output each slide as an image with
--images png - Automated CI/CD builds: Naturally integrates into CLI pipelines
- Team collaboration: Easy to review as Markdown, merge conflicts are easier to resolve
When Reveal.js is the right fit
- Conference talks: Control audience attention with fragment animations and vertical slides
- Recording technical videos: Step-by-step code line highlighting is ideal for Fireship-style walkthroughs
- Interactive demos: Dynamic content can be embedded via JS plugins
- When polished visual production is required: Background gradients, custom animations
Summary
| Aspect | Marp | Reveal.js |
|---|---|---|
| Creation speed | Fast | Moderate |
| Source readability | Excellent (Markdown) | Low (HTML) |
| Animations | None | Rich |
| Code highlight control | Basic | Step-by-step per line |
| Export | HTML/PDF/PPTX/images | HTML (others require separate tools) |
| Git compatibility | Excellent | Possible but diffs are hard to read |
| Visual freedom | Moderate | Unlimited |
In conclusion, the two are not competing tools — they serve different purposes.
- Marp = everyday slides: Presentations as an extension of documentation. Write it, version-control it, and convert to PPTX or PNG as needed.
- Reveal.js = high-stakes presentations: Craft the audience experience through animations and interaction.
Personally, I felt that Marp can comfortably cover about 80% of day-to-day work. Its greatest advantage is that it can be bundled into a codebase as a Markdown file, allowing presentations to be treated as "artifacts version-controlled alongside code." Reveal.js is best reserved for conference talks and technical videos where production quality directly impacts outcomes.