scrollytelling-marp
v0.1.0
Published
Turn a Marp deck into a scrollytelling HTML page.
Readme
scrollytelling-marp
Turn a Marp deck into a scrollytelling HTML page.
One sticky slide on the left, speaker notes as the scrolling prose on the right, active slide swaps as you scroll. One self-contained HTML file. Zero runtime dependencies in the emitted page.
Inspired by Maggie Appleton's zero-alignment essay.
Install
npm install -g scrollytelling-marpUse
scrollytelling-marp deck.md -o deck.html
scrollytelling-marp deck.md --pane-side right
scrollytelling-marp deck.md --css custom.css --title "My essay"The deck is a normal Marp deck. The only rule: speaker notes become the scrolling prose for that slide. No new syntax.
---
marp: true
theme: default
---
# First slide
<!--
This is the scrolling prose for slide 1.
Markdown works — **bold**, [links](https://example.com), lists, code.
-->
---
# Second slide
<!--
More prose for slide 2.
-->Showcase
make showcase builds examples/showcase.html — a deck that exercises
every feature:
| Slide | Demonstrates |
|---|---|
| 1 | Title + ![bg] + rich-markdown note |
| 2 | Per-slide theme override |
| 3 | TypeScript code fence with syntax highlighting |
| 4 | Inline and display math (MathJax in marp-core 4.x) |
| 5 | Emoji shortcodes |
| 6 | Heading, lists, inline code, links — all in notes |
| 7 | A slide with no notes (empty prose section, visual continuity) |
| 8 | A long multi-paragraph note (scroll budget) |
| 9 | Local image asset |
CLI flags
| Flag | Default | Purpose |
|---|---|---|
| -o, --output <path> | <deckname>.html | Output file |
| --pane-side left\|right | left | Which side the sticky slide sits on |
| --css <path> | — | Extra stylesheet inlined after page CSS |
| --title <string> | scrollytelling-marp | Page <title> |
Programmatic API
import { buildFromFile, buildFromString } from 'scrollytelling-marp';
const html = await buildFromFile('deck.md', { paneSide: 'right' });How it works
- Uses
@marp-team/marp-corewithinlineSVG: true— each slide becomes an inline<svg>with a<foreignObject>. No Chromium dependency. - Uses
markdown-itto render speaker notes as HTML (raw HTML disabled). - Scroll tracking is vanilla
IntersectionObserver— a section becomes active when it crosses the middle of the viewport. - Everything inlines into one HTML file.
Not yet supported
See docs/plans/2026-04-23-scrolling-marp-design.md → Future work.
