Marp and Slidev alternative inside a React app
Start with what this does not do. Marp and Slidev
export decks to PDF and PPTX from the command line.
reveal.js prints to PDF from the browser.
@react-markdown-kit/slides has no export command and writes no PPTX. If the
deliverable is a file to email, use one of those three.
What it does instead: it turns Markdown your React app already renders into a deck, in
the same page, through the same <Markdown> component. No second toolchain, no second
copy of the content, no static site to deploy beside your app.
npm install @react-markdown-kit/renderer @react-markdown-kit/slides
import Markdown, { defineMarkdownPreset } from '@react-markdown-kit/renderer'
import { slides } from '@react-markdown-kit/slides/present'
import '@react-markdown-kit/slides/styles.css'
const preset = defineMarkdownPreset({ extensions: [slides()] })
<div className="rmk-document">
<Markdown preset={preset}>{deck}</Markdown>
</div>
What each tool does
| Marp | Slidev | reveal.js | @react-markdown-kit/slides | |
|---|---|---|---|---|
| Runs as | a CLI, a VS Code extension, a bundled HTML file | a Vite dev server and a built single-page app | a page you host | a component in a React tree you already have |
| Deck source | Markdown, --- breaks, directives in HTML comments | Markdown, --- breaks, per-slide front matter, Vue components | HTML sections, or Markdown through its plugin | the same Markdown file, --- breaks, ??? notes, -- fragments (DIALECT.md) |
| Export | HTML, PDF, PPTX, PNG (Marp CLI) | PDF, PNG, PPTX (exporting) | print to PDF (PDF export) | browser print, one slide per page (styles.css); no PPTX |
| Present mode | presenter view in the editor and the CLI preview | presenter mode with notes (UI) | speaker view plugin | present mode, presenter view, cross-window sync (present.dom.test.tsx) |
| Server rendering | a build step writes the HTML | a build step writes the HTML | the page ships the deck | the deck is built from the parsed tree, so a server component emits it (same suite) |
| Styling | a theme is a CSS file of Marp's classes | UnoCSS and Vue components | a theme is a CSS file of reveal's classes | data attributes and --rmk-slide-* properties, no class from the kit (extension.test.tsx) |
| Editing | your editor, with a preview | your editor, with hot reload | your editor | the same file, plus a rich editor with four deck commands (editor-toolbar.test.tsx) |
Every claim in the last column links to the test or the file that holds it.
The deck, rendered by the kit
The deck below is not a screenshot. It was rendered when this page was built, by the same renderer that draws this paragraph. Click Present, then use the arrow keys.
Coming from a Marp deck
| Marp | Here |
|---|---|
--- between slides | the same, at the root of the document |
<!-- _class: lead --> on one slide | <!-- class: center, middle -->, one directive per comment |
<!-- theme: gaia --> | a stylesheet of yours, set through --rmk-slide-* properties |
| notes in an HTML comment | a paragraph that is exactly ???, then the notes |
fragments from the list marker, * for bullets and ) for ordered lists (fragmented list) | a paragraph that is exactly -- between the blocks to reveal |
background images through  | <!-- background: … -->, run through the renderer's URL policy |
| front matter for the whole deck | front matter for the whole deck: title, aspect, class, background |
The dialect is written out in DIALECT.md and on the slides page. A construct the plugin does not accept is reported as a diagnostic with its source range, not swallowed.
Stay with Marp or Slidev when
- The output is a file. A PDF for a conference upload, or a PPTX for a colleague who edits in PowerPoint, is their job and not this plugin's.
- The deck is a standalone artefact with no app around it, and a CLI is the shorter path.
- You want Vue components, UnoCSS or Monaco inside slides, which is Slidev's design.
- You want a theme you can install. Marp and reveal.js both have theme ecosystems; this has CSS custom properties and no themes to install.
Use this plugin when
- The content already lives in your React app and is already rendered as Markdown. A deck then costs one preset, not a second pipeline.
- The deck must sit behind your auth, your routing or your data. It is a component, so the page around it is yours.
- The same file has to stay readable as a document. A deck is CommonMark or GFM with rules, so GitHub and a diff still show it as prose.
- The deck must render on the server. It is built from the parsed tree by a root handler, so a server component emits the full markup.
- The document is edited by people who do not write Markdown by hand. The editor entry adds New slide, Speaker notes, Pause and Background as toolbar buttons, tested in editor-toolbar.test.tsx.
What a CLI cannot give you
- One source. The deck and the document are the same file, and a deck loaded and saved without edits is written back byte for byte (round-trip.test.ts).
- The renderer's security policy. A
javascript:background loses itssrclike any other URL in the document (extension.test.tsx), under the same security model as your prose. - Markup you can style. The deck emits no class, no inline style and no id beyond
slide-<name>, so your stylesheet needs nothing from the kit. - No runtime for the static deck. The root entry loads nothing beyond the parser. React comes in with the present entry, Lexical only with the editor entry (packaging.test.ts).
Questions
- Is there a Marp alternative that runs inside a React app?
- This plugin is one. It adds slide rules to the Markdown renderer you already use, so a deck is a component in your own routes rather than a separate site or a build step.
- Can I export a deck to PDF or PPTX?
- There is no export command. The shipped stylesheet gives each slide its own page under @media print, so a browser prints a deck to PDF. PPTX is what Marp and Slidev do; this does not.
- Does an existing Marp deck render unchanged?
- The slide breaks, the prose and the code fences do. Marp directives, themes and its image sizing syntax do not; the mapping table on this page says what each one becomes.
- Do I have to move my content out of my app?
- No. The deck is the same Markdown file the renderer already reads, so a document and a deck are one source and one pipeline.
Next
The slides demo · The demo without its chrome, for an iframe · Markdown presentations in React · @react-markdown-kit/slides on npm · The renderer · Security model