Slidev vs Marp vs Reveal.js: Code-First Presentations Compared (2026)
TL;DR: Slidev is the Vue-powered presentation framework — Markdown slides with Vue components, code highlighting with animations, presenter mode, and recording built in. Marp is the Markdown-to-slide converter — write Markdown, export to HTML/PDF/PPTX, integrate with VS Code, and keep presentations in version control. Reveal.js is the original HTML presentation framework — plugin ecosystem, speaker notes, multiplexing, and the most customizable option for complex slide decks. In 2026: Slidev for interactive developer presentations with live code, Marp for simple Markdown-to-PDF slide decks, Reveal.js for maximum customization and plugin ecosystem.
Key Takeaways
- Slidev: Vue 3 + Vite powered. Markdown + Vue components, Shiki code highlighting with line animations, LaTeX math, presenter mode, recording. Best for developer conference talks with live code demos
- Marp: Pure Markdown → slides. VS Code extension, CLI for HTML/PDF/PPTX export, theme engine, directives for styling. Best for quick slide decks from Markdown with zero setup
- Reveal.js: HTML/Markdown framework. Plugin architecture, speaker notes, auto-animate, multiplexing, PDF export. Best for highly customized presentations with complex animations
Slidev — Vue-Powered Presentations
Slidev combines Markdown simplicity with Vue component power — write slides in Markdown, embed interactive components, and present with live code.
Basic Slide Deck
---
theme: default
title: Building APIs with Hono
info: |
## Building APIs with Hono
A talk about modern API development
class: text-center
drawings:
persist: false
transition: slide-left
mdc: true
---
# Building APIs with Hono
The lightweight framework for every runtime
<div class="abs-br m-6 flex gap-2">
<a href="https://github.com/honojs/hono" target="_blank">
<carbon-logo-github class="text-xl" />
</a>
</div>
---
transition: fade-out
---
# Why Hono?
- 🚀 **Fast** — Built on Web Standards
- 🌐 **Universal** — Runs on Cloudflare, Deno, Bun, Node.js
- 📦 **Tiny** — ~14KB, zero dependencies
- 🔒 **Type-safe** — Full TypeScript support
---
layout: two-cols
layoutClass: gap-16
---
# Setup
Install and create a Hono app in seconds.
::right::
```ts {all|1|3-5|7-9|all}
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.json({ hello: 'world' }))
export default app
layout: center class: text-center
Demo Time
Feature Comparison
| Feature | Hono | Express | Fastify |
|---|---|---|---|
| Bundle Size | 14KB | 200KB | 2MB |
| TypeScript | Native | @types | Native |
| Runtime | Any | Node.js | Node.js |
layout: end
Thank You!
### Code Highlighting with Animations
```markdown
---
# Code Walkthrough
Step through code line by line:
```ts {1|2-4|6-10|all}
import { Hono } from 'hono'
// Create app instance
const app = new Hono()
// Define routes with type safety
app.get('/users/:id', async (c) => {
const id = c.req.param('id')
const user = await getUser(id)
return c.json(user)
})
// Start server
export default app
Diff Highlighting
Show code changes:
// Before
app.get('/users', (c) => {
const users = db.getAll()
return c.json(users)
})
~~~
// After
app.get('/users', async (c) => {
const users = await db.getAll()
return c.json(users, 200, {
'Cache-Control': 'max-age=60'
})
})
### Vue Components in Slides
```vue
<!-- components/Counter.vue — used directly in slides -->
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
<template>
<div class="flex items-center gap-4">
<button @click="count--" class="btn">-</button>
<span class="text-4xl font-bold">{{ count }}</span>
<button @click="count++" class="btn">+</button>
</div>
</template>
<!-- In your slide markdown: -->
<!-- <Counter /> -->
---
# Interactive Demo
<Counter />
Click the buttons — this is a live Vue component in your slides!
---
# Live API Demo
<div v-click>
```ts
const response = await fetch('/api/demo')
const data = await response.json()
Result:
### CLI and Export
```bash
# Install and create a project
npm init slidev@latest my-talk
# Start dev server with hot reload
npx slidev
# Build for production (SPA)
npx slidev build
# Export to PDF
npx slidev export
# Export to PNG images
npx slidev export --format png
# Record presentation
npx slidev --record
# Presenter camera + slides recorded together
# Deploy to Netlify/Vercel
npx slidev build
# Upload dist/ folder
Marp — Markdown to Slides
Marp converts Markdown to presentation slides — write in VS Code, export to HTML, PDF, or PowerPoint.
Basic Slide Deck
---
marp: true
theme: default
paginate: true
header: "Building APIs with Hono"
footer: "Your Name — March 2026"
---
# Building APIs with Hono
The lightweight framework for every runtime
---
## Why Hono?
- 🚀 **Fast** — Built on Web Standards
- 🌐 **Universal** — Cloudflare, Deno, Bun, Node.js
- 📦 **Tiny** — ~14KB, zero dependencies
- 🔒 **Type-safe** — Full TypeScript support
---
## Quick Setup
```ts
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.json({ hello: 'world' }))
export default app
Feature Comparison
| Feature | Hono | Express | Fastify |
|---|---|---|---|
| Bundle Size | 14KB | 200KB | 2MB |
| TypeScript | Native | @types | Native |
| Runtime | Any | Node.js | Node.js |
Thank You!
### Directives and Styling
```markdown
---
marp: true
theme: uncover
style: |
section {
background-color: #1a1a2e;
color: #eee;
}
h1 {
color: #0fd;
}
code {
background: #16213e;
}
section.lead {
text-align: center;
}
section.split {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2em;
}
---
<!-- _backgroundColor: #0d1117 -->
<!-- _color: white -->
# Dark Slide
This slide has a custom dark background.
---
<!-- _class: split -->
# Two Columns
Left content here with explanation text.
Right content here with code example:
```ts
const app = new Hono()

Background Images
Marp supports background images with positioning:
bg— full backgroundbg right:40%— right 40%bg left— left halfbg contain— fit insidebg cover— cover entire slide
Math Support
Inline: $E = mc^2$
Block:
$$ \sum_{i=1}^{n} x_i = x_1 + x_2 + \ldots + x_n $$
### Custom Theme
```css
/* themes/company.css */
/* @theme company */
@import 'default';
section {
font-family: 'Inter', sans-serif;
background: #0a0a0a;
color: #e0e0e0;
}
h1 {
color: #0fd;
font-size: 2.5em;
border-bottom: 3px solid #0fd;
padding-bottom: 0.3em;
}
h2 {
color: #0fd;
font-size: 1.8em;
}
code {
background: #1a1a2e;
border-radius: 4px;
padding: 2px 6px;
}
pre code {
font-size: 0.8em;
line-height: 1.5;
}
section.lead {
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
CLI and Export
# Install Marp CLI
npm install -g @marp-team/marp-cli
# Convert to HTML
marp slides.md -o slides.html
# Convert to PDF
marp slides.md -o slides.pdf
# Convert to PowerPoint
marp slides.md -o slides.pptx
# Convert to PNG images
marp slides.md --images png
# Watch mode with live preview
marp slides.md -w --preview
# Use custom theme
marp slides.md --theme themes/company.css -o slides.pdf
# Serve with hot reload
marp -s slides.md
# VS Code Extension — Marp for VS Code
# Preview slides directly in VS Code editor
# Export from command palette
Reveal.js — HTML Presentation Framework
Reveal.js is the original web-based presentation framework — HTML/Markdown slides with plugins, animations, and speaker notes.
Basic Presentation
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="dist/reveal.css" />
<link rel="stylesheet" href="dist/theme/dracula.css" />
<link rel="stylesheet" href="plugin/highlight/monokai.css" />
</head>
<body>
<div class="reveal">
<div class="slides">
<section>
<h1>Building APIs with Hono</h1>
<p>The lightweight framework for every runtime</p>
</section>
<section>
<h2>Why Hono?</h2>
<ul>
<li class="fragment">🚀 Fast — Web Standards</li>
<li class="fragment">🌐 Universal — Any runtime</li>
<li class="fragment">📦 Tiny — 14KB</li>
<li class="fragment">🔒 Type-safe</li>
</ul>
</section>
<section data-auto-animate>
<pre data-id="code"><code data-trim data-line-numbers>
import { Hono } from 'hono'
const app = new Hono()
</code></pre>
</section>
<section data-auto-animate>
<pre data-id="code"><code data-trim data-line-numbers="|3-5">
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.json({ hello: 'world' })
})
</code></pre>
</section>
<section>
<h2>Feature Comparison</h2>
<table>
<thead><tr><th>Feature</th><th>Hono</th><th>Express</th></tr></thead>
<tbody>
<tr><td>Size</td><td>14KB</td><td>200KB</td></tr>
<tr class="fragment"><td>TypeScript</td><td>Native</td><td>@types</td></tr>
</tbody>
</table>
</section>
<section>
<h2>Thank You!</h2>
<aside class="notes">
Remember to mention the GitHub repo and demo link.
</aside>
</section>
</div>
</div>
<script src="dist/reveal.js"></script>
<script src="plugin/highlight/highlight.js"></script>
<script src="plugin/notes/notes.js"></script>
<script src="plugin/math/math.js"></script>
<script>
Reveal.initialize({
hash: true,
plugins: [RevealHighlight, RevealNotes, RevealMath.KaTeX],
transition: 'slide',
slideNumber: true,
});
</script>
</body>
</html>
Markdown Content in Reveal.js
<!-- Use Markdown inside Reveal.js slides -->
<section data-markdown>
<textarea data-template>
## Slide 1
Write slides in **Markdown** within Reveal.js.
---
## Code Example
```ts [1|2-4|6]
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.json({ hello: 'world' }))
export default app
```
---
## Fragments
- Item 1 <!-- .element: class="fragment" -->
- Item 2 <!-- .element: class="fragment" -->
- Item 3 <!-- .element: class="fragment" -->
</textarea>
</section>
<!-- External Markdown file -->
<section
data-markdown="slides.md"
data-separator="^\n---\n"
data-separator-vertical="^\n--\n"
data-separator-notes="^Note:"
></section>
Programmatic API
// Initialize with full configuration
import Reveal from "reveal.js";
import Markdown from "reveal.js/plugin/markdown/markdown";
import Highlight from "reveal.js/plugin/highlight/highlight";
import Notes from "reveal.js/plugin/notes/notes";
import Math from "reveal.js/plugin/math/math";
const deck = new Reveal({
plugins: [Markdown, Highlight, Notes, Math],
hash: true,
transition: "convex",
slideNumber: "c/t",
autoAnimateDuration: 0.7,
pdfMaxPagesPerSlide: 1,
// Multiplexing — control from one device, view on others
multiplex: {
secret: "presenter-secret",
id: "presentation-id",
url: "https://reveal-multiplex.glitch.me/",
},
});
deck.initialize().then(() => {
// Listen to slide change events
deck.on("slidechanged", (event) => {
console.log(`Slide ${event.indexh}.${event.indexv}`);
trackSlideView(event.indexh);
});
// Navigate programmatically
deck.slide(2, 0); // Go to slide 3
// Get total slides
console.log(`Total: ${deck.getTotalSlides()}`);
});
Feature Comparison
| Feature | Slidev | Marp | Reveal.js |
|---|---|---|---|
| Content Format | Markdown + Vue | Pure Markdown | HTML + Markdown |
| Framework | Vue 3 + Vite | Marpit engine | Vanilla JS |
| Code Highlighting | Shiki (line animations) | Prism/Shiki | highlight.js |
| Line-by-Line Code | ✅ (animated) | ❌ | ✅ (data-line-numbers) |
| Live Components | ✅ (Vue components) | ❌ | ✅ (HTML/JS) |
| Animations | Vue transitions + v-click | ❌ | Auto-animate + fragments |
| Speaker Notes | ✅ (presenter mode) | ❌ | ✅ (speaker view) |
| Recording | ✅ (built-in) | ❌ | ❌ |
| Math/LaTeX | ✅ (KaTeX) | ✅ (KaTeX/MathJax) | ✅ (KaTeX/MathJax) |
| Themes | Built-in + custom | Built-in + CSS | Built-in + custom |
| PDF Export | ✅ | ✅ | ✅ |
| PPTX Export | ❌ | ✅ | ❌ |
| VS Code Integration | ❌ | ✅ (extension) | ❌ |
| Plugin Ecosystem | Vue ecosystem | Limited | Rich (multiplex, etc.) |
| Multiplexing | ❌ | ❌ | ✅ (remote control) |
| SPA Deploy | ✅ (Vite build) | ✅ (HTML) | ✅ (HTML) |
| Hot Reload | ✅ | ✅ (watch mode) | Manual |
| Learning Curve | Medium (Vue knowledge helps) | Low | Medium-High |
| Best For | Dev conference talks | Quick Markdown slides | Customized presentations |
When to Use Each
Choose Slidev if:
- You're giving developer conference talks with live code demos
- Vue components for interactive elements add value to your slides
- Step-by-step code walkthroughs with line highlighting are important
- Built-in recording for asynchronous talks is useful
- You want the best developer presentation experience with hot reload
Choose Marp if:
- You want the simplest Markdown-to-slides workflow
- VS Code integration for editing and previewing is important
- PowerPoint export (PPTX) is needed for corporate environments
- Version-controlled Markdown presentations fit your workflow
- Minimal setup — write Markdown, export, present
Choose Reveal.js if:
- Maximum customization with HTML, CSS, and JavaScript is needed
- The plugin ecosystem (multiplexing, custom plugins) matters
- Auto-animate transitions between slides create visual impact
- Speaker notes with a separate presenter view are essential
- You want full control over every aspect of the presentation
Methodology
Feature comparison based on Slidev v0.x, Marp CLI v3.x, and Reveal.js v5.x documentation as of March 2026. Slidev evaluated on Vue integration, code highlighting, and presenter features. Marp evaluated on Markdown simplicity and export formats. Reveal.js evaluated on plugin ecosystem, animations, and customization. Code examples use official APIs and configuration.