Articles
Published · October 24, 2026

Markdown Slides: Building Presentations with Marp and Reveal.js

Marp and reveal.js both turn Markdown into slides. Marp exports HTML, PDF and PPTX from one file; reveal.js builds a web deck. Here is how each one works.

Use Marp if you want a slide deck that is one Markdown file you can export to HTML, PDF or PPTX. Use reveal.js if you want a web presentation with animations and a JavaScript API. Both let you write slides as plain text instead of dragging boxes around.

Quick answer

A Markdown slide deck is a text file where a line of three dashes starts a new slide. That's the whole idea. Marp reads the file and renders slides with a theme. reveal.js loads the same kind of text inside a web page. Because the deck is plain text, it diffs cleanly in Git, you can edit it anywhere, and nobody has to open a slide editor to fix a typo.

Marp: a deck is one Markdown file

Marp is built in layers. Marpit is the framework that turns Markdown plus CSS into slides, Marp Core adds built-in themes, and Marp CLI does the conversion. Here is a small deck:

---
theme: default
paginate: true
---

<!-- _class: lead -->
# Release review

---

## What shipped

- Faster search
- Fewer sync conflicts

The block at the top is YAML front matter. Per the Marpit directives docs, a --- ruler starts a new slide, and settings like theme and paginate live in that front matter or in HTML comments.

Directives: global, local and spot

Directives come in three scopes:

  • Global directives such as theme and style apply to the whole deck. If you write one twice, the last value wins.
  • Local directives such as paginate, header, footer, class and backgroundColor apply to the current slide and every slide after it.
  • Spot directives add an underscore prefix and apply to one slide only.
<!-- backgroundColor: aqua -->
This slide and the next are aqua.

---

<!-- _backgroundColor: black -->
<!-- _color: white -->
Only this slide is black.

Setting class: lead adds a class to the slide's section element, which themes can target for centered title slides.

Exporting a Marp deck

Marp CLI runs through npx if you have Node.js v18 or later:

npx @marp-team/marp-cli@latest slides.md          # HTML (default)
npx @marp-team/marp-cli@latest slides.md --pdf
npx @marp-team/marp-cli@latest slides.md --pptx
npx @marp-team/marp-cli@latest slides.md --watch

HTML is the default output. PDF, PPTX and image export need Google Chrome, Microsoft Edge or Firefox installed, according to the Marp CLI README. Add --watch and it reconverts whenever the Markdown or a theme file changes, so you can keep the HTML open in a browser while you write.

Before you promise a colleague an editable PowerPoint file, know two details. Standard --pptx output contains rendered slide pages and supports presenter notes. There is also an experimental --pptx-editable flag that produces editable text, shapes and images, but it needs both a browser and LibreOffice Impress. The CLI docs warn it may throw an error or give an incomplete result, has lower slide reproducibility, and does not support presenter notes. For handouts, PDF is the safer choice. Add --pdf-notes if you want notes annotated in the PDF.

reveal.js: Markdown inside a web page

reveal.js is a web presentation framework, and Markdown is an optional plugin. Per the reveal.js Markdown docs, you add data-markdown to a section and put the text in a textarea template:

<section data-markdown>
  <textarea data-template>
    ## First slide
    ---
    ## Second slide
    Note: Say this part out loud.
  </textarea>
</section>

Slides separate on --- by default. Vertical slides are off until you set data-separator-vertical, and both separators are regular expressions. Speaker notes start after a line beginning Note:. Attributes go in HTML comments: <!-- .element: class="fragment" --> makes the element above a step-by-step fragment, and <!-- .slide: ... --> styles the whole slide. The default example presentations already load the plugin; in your own page you pass RevealMarkdown to the plugins array.

Local server and Node version

You can also keep slides in a separate file with data-markdown="slides.md". That requires reveal.js to run from a local web server, so opening index.html straight from disk won't work. The installation guide recommends the full setup: clone the repo, run npm install, then npm start and open http://localhost:8000. That setup needs Node.js 20.19.0 or later. The basic setup, a downloaded archive opened in a browser, needs no tooling but can't load external Markdown.

PDF export

Open the deck with ?print-pdf appended, such as http://localhost:8000/?print-pdf, then print to PDF with landscape layout, no margins and background graphics enabled. The PDF export page says this is confirmed only in Chrome and Chromium.

Choosing between them

Marp is the lower-effort path from text to a file you can hand over. It suits internal training, docs repos and anyone who just wants slides without managing a web project. Its theme and directive model is deliberately small, so it's less suited to heavy animation. reveal.js gives you more control, including fragments, vertical slides and a JavaScript API, but it behaves like a small website: you manage HTML, CSS and a dev server. A 2026 comparison from PkgPulse reaches the same split, calling Marp the pick for portable Markdown slide documents and reveal.js the one for custom web behavior.

If your slides need a diagram, look at the diagram-as-code tools that render from text.

Doing this with Carets

Both tools start with a text file. That's where Carets fits. Carets is a native notes and code editor for iPhone, iPad and Mac that handles Markdown, plain text and code in one place. You can draft the deck as a .md file with Markdown highlighting, and keep the HTML and CSS for a reveal.js page in the same project with syntax highlighting. Files, projects and tags let you keep each talk's source together. The files stay plain text, so they're portable: run Marp CLI or npm start on your Mac and the same file works.

Carets is an editor, not a slide renderer. You'll still use Marp or reveal.js to build the output. Get Carets on the App Store for iPhone, iPad and Mac.

Frequently Asked Questions

Can Marp export an editable PowerPoint file?

Standard --pptx output contains rendered slide pages. The experimental --pptx-editable flag produces editable text, shapes and images, but it needs a browser plus LibreOffice Impress, may give incomplete results, and does not support presenter notes.

Do I need Node.js to use Marp?

Marp CLI runs through npx and needs Node.js v18 or later. Marp CLI is also available as a standalone binary and a Docker image, and there is a Marp extension for VS Code.

Why does my reveal.js external Markdown file not load?

Loading slides from a separate file needs reveal.js to run from a local web server. Opening index.html straight from disk will not work. Run npm start and use localhost instead.

How do I add speaker notes?

In reveal.js, start a line with Note: inside the slide. In Marp, notes are HTML comments that aren't directives, and PPTX export carries them while --pdf-notes annotates them in a PDF.