Skip to content

Marp & Slidev compatibility

astro-slides renders many existing Marp and Slidev decks with little to no editing. Compatibility is handled at the parser level: Slidev directives and Marp shorthand are rewritten into astro-slides’ native model before rendering, so they share the same code path — and the same semantics — as decks authored natively.

Slidev’s click directives are rewritten to astro-slides’ native <Click> / <After> / <Clicks> components before click numbering runs, so they get the exact same step semantics as native reveals. Both the element form and the attribute form are supported.

<!-- Element form -->
<v-click>Revealed on the first click</v-click>
<v-after>Revealed with the previous step</v-after>
<v-clicks>
- These list items
- reveal together
</v-clicks>
<!-- A value moves to `at` -->
<v-click="3">Revealed on click 3</v-click>

The attribute form wraps any element it’s placed on:

<!-- v-click="+1" becomes <Click at="+1"> around this element -->
<div v-click="+1">Relative step</div>
SlidevMaps to
<v-click> / v-click attr<Click>
<v-after> / v-after attr<After>
<v-clicks> / v-clicks attr<Clicks>

Set marp: true in the deck’s headmatter to enable Marp mode. This turns on Marp-specific parsing — directive comments and image shorthand — that is intentionally off for native MDX decks (so an MDX deck that legitimately uses ![bg]-style alt text isn’t affected).

---
marp: true
theme: marp-default
---
# My Marp deck

Marp global, local, and scoped directive comments map to slide frontmatter — for example _backgroundColor becomes the slide background, and _class is carried through.

<!-- _class: lead -->
<!-- _backgroundColor: #101020 -->

In Marp mode, Marp’s image shorthand is rewritten:

![bg](city.jpg) <!-- becomes the slide background -->
![bg cover](city.jpg) <!-- background, cover-fit -->
![w:200 h:120](logo.png) <!-- inline <img> with width/height -->

A set of Slidev components ship as shims so decks that use them render without edits:

ComponentBehavior
YoutubeEmbeds a YouTube iframe.
TweetLink-card fallback (a live embed isn’t shipped).
TocRenders a table of contents from the slide titles.
VDragStatic absolute positioning — honors pos, but interactive drag isn’t supported.
AutoFitTextAlias of astro-slides’ fit-text primitive.
LightOrDarkLight/dark named slots, toggled on the color scheme.
<Youtube id="dQw4w9WgXcQ" />
<Toc />

Three Marp themes are ported to astro-slides’ theme-token contract and selectable by name via the theme: headmatter:

  • marp-default
  • marp-gaia
  • marp-uncover
---
marp: true
theme: marp-gaia
---

Each theme re-values astro-slides’ --slide-* tokens to approximate the original Marp look. As with all compatibility here, the goal is a faithful feel, not a pixel match.

  • docs/built/15-marp-slidev-compatibility.md — the distilled phase writeup, including the full gap list.
  • packages/core/src/compat/remark-slidev.ts — the v-click family rewriter.
  • packages/parser/src/marp.tsextractMarpDirectives + extractMarpImages.
  • packages/client/components/{Youtube,Tweet,Toc,VDrag,AutoFitText,LightOrDark}.astro — the Slidev shims.
  • packages/client/src/themes/marp-{default,gaia,uncover}/theme.css — the Marp theme ports.