Skip to main content

Slidev vs Marp vs Reveal.js: Code-First Presentations Compared (2026)

·PkgPulse Team

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

FeatureHonoExpressFastify
Bundle Size14KB200KB2MB
TypeScriptNative@typesNative
RuntimeAnyNode.jsNode.js

layout: end

Thank You!

Slides · GitHub


### 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

FeatureHonoExpressFastify
Bundle Size14KB200KB2MB
TypeScriptNative@typesNative
RuntimeAnyNode.jsNode.js

Thank You!

@yourhandle


### 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()

bg right:40%

Background Images

Marp supports background images with positioning:

  • bg — full background
  • bg right:40% — right 40%
  • bg left — left half
  • bg contain — fit inside
  • bg 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

FeatureSlidevMarpReveal.js
Content FormatMarkdown + VuePure MarkdownHTML + Markdown
FrameworkVue 3 + ViteMarpit engineVanilla JS
Code HighlightingShiki (line animations)Prism/Shikihighlight.js
Line-by-Line Code✅ (animated)✅ (data-line-numbers)
Live Components✅ (Vue components)✅ (HTML/JS)
AnimationsVue transitions + v-clickAuto-animate + fragments
Speaker Notes✅ (presenter mode)✅ (speaker view)
Recording✅ (built-in)
Math/LaTeX✅ (KaTeX)✅ (KaTeX/MathJax)✅ (KaTeX/MathJax)
ThemesBuilt-in + customBuilt-in + CSSBuilt-in + custom
PDF Export
PPTX Export
VS Code Integration✅ (extension)
Plugin EcosystemVue ecosystemLimitedRich (multiplex, etc.)
Multiplexing✅ (remote control)
SPA Deploy✅ (Vite build)✅ (HTML)✅ (HTML)
Hot Reload✅ (watch mode)Manual
Learning CurveMedium (Vue knowledge helps)LowMedium-High
Best ForDev conference talksQuick Markdown slidesCustomized 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.

Comments

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.