Marp vs Reveal.js built from identical content — Markdown slides vs an HTML framework
Building the same deck in Marp and Reveal.js: source readability at 243 vs 287 lines, the animation gap, export formats, and which one fits which job.

On this page
Introduction
Beyond PowerPoint and Google Slides, there are slide tools you can manage as code. Two representative ones are Marp, which generates slides from Markdown, and Reveal.js, an HTML/JS presentation framework.
To work out which fits my use case, I built the same content in both tools and compared them.
Prerequisites and environment
- macOS (Apple Silicon)
- Node.js 22.x
- pnpm 11.x
- Marp CLI 4.4.0
- Reveal.js 5.1.0 (via CDN)
What Marp is
Marp stands for “Markdown Presentation Ecosystem”, a tool that generates presentation slides from Markdown files.
Main characteristics:
- Text written in Markdown becomes the slide directly
---(a horizontal rule) separates slides- The CLI converts to HTML, PDF, PPTX, and PNG
- The VS Code extension supports live preview
- Themes and styles are set in frontmatter
What Reveal.js is
Reveal.js is a presentation framework based on HTML, CSS, and JavaScript. It is also the technology behind slides.com.
Main characteristics:
- Fragment animation (revealing elements one at a time)
- Vertical slides (a drill-down structure)
- Smooth transitions via
data-auto-animate - Code line highlighting via
data-line-numbers - A plugin ecosystem (maths, notes, search, and more)
Setup
Marp
Installing the VS Code extension marp-team.marp-vscode gives you live slide preview inside the editor. The CLI installs as follows:
# Install the CLIpnpm add -D @marp-team/marp-cli
# Build the slidespnpm dlx @marp-team/marp-cli slides.md -o slides.html
# PDF outputpnpm dlx @marp-team/marp-cli slides.md -o slides.pdf
# PPTX outputpnpm 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 pngThe output format is detected automatically from the extension. PDF output requires Chrome or Chromium; HTML and PPTX work as-is.
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 there is nothing to install and a single HTML file is self-contained. To install locally, use pnpm add reveal.js.
Building the same content in both
For test content I turned an article I wrote earlier, about AI coding CLI tools and SSD writes, into a presentation. It contains code blocks, tables, data comparisons, and a narrative flow, which makes it a good subject for exposing what each tool is and is not good at.
The demo I built is published in this repository:
https://github.com/oharu121/marp-reveal-js-demo
Marp source (excerpt)
---marp: truetheme: defaultpaginate: truebackgroundColor: #1a1a2ecolor: #eeestyle: | 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>Points to note:
- The
style:block in frontmatter customises the CSS <!-- _class: lead -->applies the title-slide layout<div class="columns">produces a two-column layout (HTML embedded in Markdown)- Tables, quotes, and code blocks are all plain standard Markdown
Reveal.js source (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 down arrow 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: clicking moves the focus --><section> <pre><code class="language-bash" data-line-numbers="1-2|4-5|7-12">$ du -sh ~/.claude/debug2.8M ~/.claude/debug # Normal
$ du -sh ~/.claude/file-history12M ~/.claude/file-history # Normal
$ du -sh ~/.claude/*/ | sort -hr | head -5866M plugins/434M projects/266M security/ 12M file-history/2.8M debug/ </code></pre></section>Points to note:
class="fragment"animates elements appearing one at a time- Nesting
<section>produces vertical slides (drill-down) data-line-numbers="1-2|4-5|7-12"highlights code lines step by stepdata-auto-animategives smooth transitions between slidesdata-background-gradientchanges the background per slide
Comparison results
Source readability
Marp’s source is Markdown you can just read. Previewed on GitHub or opened in VS Code, the content is clear.
# Marp source: 243 lines of Markdown$ wc -l slides.md243
# Reveal.js source: 287 lines of HTML$ wc -l index.html287By line count there is not much in it. By what those lines hold, it inverts. Counting every line whose entire content is one or more HTML tags and nothing else, Reveal.js spends 115 of its 287 lines, 40%, on markup alone, against Marp’s 19 of 243. Subtract the markup and the blanks and Marp carries more content in fewer total lines: 162 lines against 152.
</section> or <div class="columns">.That is what makes Marp’s source double as documentation while Reveal.js’s needs an HTML parser.
Animation and transitions
This is the biggest difference.
Marp has no in-slide animation. --- switches slides and that is it.
In Reveal.js:
- Fragments: reveal table rows one at a time, uncover a conclusion in stages
- Vertical slides: keep the main flow while drilling down into detail
- Code line highlighting:
data-line-numbers="1-2|4-5"moves the focus on each click - auto-animate: elements move smoothly between slides
For technical videos (Fireship-style code explanations) and conference talks, this difference is decisive.
Export
| Output format | Marp | Reveal.js |
|---|---|---|
| HTML | Built in | Built in |
| Built in (needs Chrome) | Separate tool required (decktape and similar) | |
| PPTX | Built in | Not supported |
| PNG/JPG images | Built in (--images) | Not supported |
Marp’s PPTX output is handy when you need to hand a file to stakeholders who use PowerPoint. --images png can be posted straight to a social carousel.
Fit with CI/CD
Marp gives you a natural md → html/pdf/pptx CLI pipeline:
# Build the slides automatically in GitHub Actionspnpm dlx @marp-team/marp-cli slides.md -o dist/slides.htmlReveal.js is static HTML, so it needs no build step at all, but automating PDF export requires a headless browser.
Themes and styling
Marp lets you scope CSS from the style: block in frontmatter. There are constraints, but basic customisation of colours, fonts, table styles, and backgrounds is perfectly possible.
Reveal.js gives you full CSS and JS, so there is no ceiling. CSS variables (--r-heading-color and others) make theme adjustment easy, and complex layouts are entirely free.
Choosing by use case
Where Marp fits
- Weekly meetings and sprint reviews: write quickly in Markdown, manage in Git, track diffs
- Turning internal documentation into slides: add
---to an existing Markdown document and it is a deck - LinkedIn and Instagram carousel posts:
--images pngexports each slide as an image - Automated builds in CI/CD: slots naturally into a CLI pipeline
- Collaborative editing in a team: Markdown reviews well and merge conflicts resolve easily
Where Reveal.js fits
- Conference talks: fragment animation and vertical slides control where the audience looks
- Recording technical videos: stepping through code line highlights suits Fireship-style explanation
- Interactive demos: JS plugins can embed dynamic content
- When elaborate visual production is required: background gradients, custom animation
Summary
| Aspect | Marp | Reveal.js |
|---|---|---|
| Authoring speed | Fast | Moderate |
| Source readability | Excellent (Markdown) | Low (HTML) |
| Animation | None | Plentiful |
| Code highlight control | Basic | Line-by-line stepping |
| Export | HTML/PDF/PPTX/images | HTML (the rest needs other tools) |
| Fit with Git | Excellent | Possible, but diffs are hard to read |
| Visual freedom | Moderate | Unlimited |
The conclusion is that these are not competing tools; they have different purposes.
- Marp = everyday slides: presentation as an extension of documentation. Write it, version it, convert to PPTX or PNG when needed
- Reveal.js = the talk that matters: build the audience’s experience out of animation and interaction
Personally, I found Marp covers 80% of day-to-day work comfortably. Its biggest advantage is that it ships inside the codebase as a Markdown file, so a presentation becomes an artefact you version alongside the code. Reveal.js is worth switching to for conference talks and technical videos, where production values feed directly into the result.




