markdown to powerpoint · compared
Lutrin vs Marp
Marp turns Markdown plus CSS into slides, then drives a browser to produce PDF, PPTX and images — you keep full control of the look. Lutrin takes the opposite bet: it refuses all positioning, so that the engine can write native PowerPoint shapes the recipient can edit. Neither of those is a better tool. They are different trades, and this page is about which one you want.
What Marp does better
This comes first because it is the part that decides whether the rest of the page is worth reading. If any of these four is what you need, close this tab and use Marp — it is a good tool, and it is free.
Four things Marp does that Lutrin does not, and will not
- Complete visual control. A Marp theme is ordinary
CSS over a
<section>, and the Marpit documentation explicitly blessesposition: absoluteas the way to place something exactly where you want it. Lutrin structurally refuses this: a contribution that let the author position an element "will be refused, however well implemented". If you have a brand deck in CSS and a logo that must sit at a precise spot, Marp does it and Lutrin tells you no. - Notes as PDF annotations, and a presenter-notes text
dump.
--pdf-noteswrites each slide's notes into the PDF as annotation objects a reader can open. Lutrin now writes PDF, PNG and JPEG of its own —--pdfgives one page per slide with an outline to navigate by,--pngand--jpegone file per slide at twice the slide size — but the notes are not in them. Writing PDF annotation objects means shipping a PDF library, and this compiler will not take a dependency for one flag: the notes stay in the.pptxand in the HTML presenter view. - Maturity, reach, and a richer web deck. The VS Code
extension reported 827,114 installs when this page was checked, and it
is a web extension that works on vscode.dev with nothing installed at
all — Lutrin's extension is desktop-only and has nothing to answer
that with. Marp's HTML template has View Transition slide
transitions, which Lutrin has no answer to either; there
is a large third-party theme ecosystem. Lutrin does have a
browser playground that runs the real
compiler with nothing installed and hands out both the
.htmland the.pptx; Mermaid, icons and images still degrade there — each one named on the page rather than dropped in silence. Anything beyond that needs Node ≥ 22 locally, and it is a young single-maintainer project.
Where Lutrin is different
- The editable
.pptxis the default, and needs no second application. This is the honest version of the claim, and the qualification matters: Marp can produce an editable PowerPoint —--pptx-editablehas shipped since Marp CLI 4.1.0. Its own documentation calls it experimental, requires LibreOffice Impress installed in addition to a browser, does not carry presenter notes, and warns of "lower slide reproducibility". Marp's default PPTX is one pre-rendered image per slide, by deliberate design — the team's stated requirement is "almost 100% reproducibility to the slide design". Lutrin has one PPTX mode: native shapes, text boxes and tables, notes kept, fonts embedded, no flag and no second program. - No browser is needed to produce the files. Marp's
PDF, PPTX and image conversions all need a compatible browser installed
(Chrome, Edge or Firefox — selectable with
--browser); with none on the machine, those formats do not come out at all. Lutrin writes both the.pptxand the HTML from Node alone, so a locked-down CI runner or a container with no Chromium still compiles. One block type does want a browser, and it is fairer to say so than to be caught at it: Mermaid measures the text it lays out, so Lutrin renders diagrams by driving a Chrome, Edge, Brave or Chromium already installed, throughpuppeteer-core— andlutrin setup-mermaid --yeswill download a ~200 MB headless shell for a machine that has none. Without one the build still succeeds: the diagram falls back to its own source as a labelled code block, and the build counts them out loud. - The engine picks the layout, not you. When a slide
overflows, Marp's answer is CSS or
<!-- fit -->, and Marp Core does shrink headers, code blocks and KaTeX to fit. Lutrin's answer is to infer a different layout and paginate what is left over. That is the trade, and it is what makes a mechanical.pptxpossible. But Lutrin shrinks as well, and pretending otherwise would be the easy version: inside a bounded region — a panel, a column, a table cell — paragraphs, bullets, tables and alerts step down the text scale one notch at a time, comfortable → compact → dense, and the whole region steps together rather than the one block that overflowed. What differs is that it stops and it says so.denseis the floor: past it the engine shrinks nothing further and reportsBLOCK_OVERFLOWinstead. And every step down comes back as aSLIDE_DENSIFIEDdiagnostic naming the region, so nothing gets smaller behind your back. - Validation that measures instead of parsing. Marp for
VS Code has completion, hover help and diagnostics for its directives —
it checks what you typed.
lutrin validate --jsonmeasures what the rendered slide does: real overflow, images under-resolved for the area they land in, a better-suited layout, printed as JSON anchored to source lines for an agent's write → validate → fix loop. - A brand that travels as data, never as code. A Marp theme is CSS the renderer executes — which is why the VS Code extension gates custom themes behind Workspace Trust. A Lutrin kit is tokens, fonts, logos and layout JSON; installing one runs nothing, refuses any entry that escapes the kit, and is https-only with a reproducible sha256.
- Diagrams, charts and status blocks are in the DSL.
Marp deliberately has none — its maintainer's position is that "Marp has
no built-in integrations for any diagrams like mermaid.js", and
recommends pre-rendered SVG instead. Lutrin ships
```chart, Mermaid, LaTeX, Lucide icons and:::metric/:::progress/:::statusas first-class blocks. Marp's math, to be clear, is not the gap: it has Pandoc-style math through MathJax or KaTeX, as does Lutrin. - Lutrin reads Marp decks. Put
marp: truein the frontmatter and the parser switches to the Marp dialect —---splits, comment notes,![bg]images, fragmented lists. It preserves content, not appearance: CSS themes,style:, per-slide backgrounds and non-16:9 sizes do not survive, and each one is reported asMARP_DIRECTIVE_IGNOREDrather than dropped in silence. The migration runs one way only.
Side by side
| Marp | Lutrin | |
|---|---|---|
| Default PPTX | One pre-rendered image per slide — contents cannot be modified in PowerPoint. A deliberate choice, for near-exact reproduction of the design. | Native shapes, text boxes and tables — real, selectable, editable — and equations as native OMML, with the rendered picture kept underneath for readers without it. Charts, diagrams and icons are pictures, each one carrying its vector as well as its raster, so PowerPoint 2019+ keeps them sharp at any zoom and every other reader draws the raster. Those three are still pictures, not editable objects, which is the honest limit of it. |
| Editable PPTX | --pptx-editable, since CLI 4.1.0. Experimental; needs LibreOffice Impress and a browser; presenter notes unsupported; lower slide reproducibility. |
The default. No flag, no second application, notes preserved. |
| Fonts in the PPTX | Not applicable to the image output; the editable path goes through LibreOffice. | TTF/OTF embedded into the OOXML, after reading the font's fsType permission — a foundry-restricted font is skipped with a warning rather than shipped. |
| Who decides the layout | You, in CSS. position: absolute is the documented technique; <!-- fit --> and auto-shrink handle overflow. |
The engine. No coordinate, size, explicit column or colour exists in the DSL. |
| Export formats | HTML, PDF, PPTX, PNG, JPEG, notes as text. | .pptx, standalone HTML, PDF (one page per slide, with an outline), PNG and JPEG (one file per slide, at 2×). No presenter-notes dump, and no notes annotations in the PDF. |
| External runtime | A browser (Chrome, Edge or Firefox) for every PDF, PPTX and image conversion. LibreOffice Impress on top, for editable PPTX. | Node ≥ 22 for .pptx and HTML, whatever is in the deck. A browser is needed for two things — rendering Mermaid, where its absence still writes the file with a reported diagnostic, and the PDF/image export, where it is required and the build refuses without it before writing a byte. |
| Branding | CSS. Three built-in themes, arbitrary custom theme CSS, a large third-party ecosystem. A theme is code the renderer runs. | Kits — tokens, fonts, logos, layout JSON. Data only; install executes nothing; WCAG contrast checked at build. |
| Diagrams & charts | None built in, by stated policy — use pre-rendered SVG. | ```chart, Mermaid, LaTeX, icons and status blocks in the DSL. |
| Math | Yes, MathJax or KaTeX. Not a Lutrin advantage. | Yes — and the same syntax is accepted in the Marp dialect. |
| Web presentation | Rich: overview, on-screen controls, progress bar, View Transition transitions, watch mode, a server mode and a preview window. | One standalone HTML file: presenter mode (P full screen, N for notes, timer, wall clock and next slide in a second window), an overview grid (O), a progress bar and on-screen controls that follow the pointer — roughly parity, in one file rather than a template. Three local servers: lutrin preview reloads on save, lutrin edit serves a tree of .deck.md files, lutrin kit edit the kit editor. No transitions engine. |
| Validation | Syntactic: completion, hover help and directive diagnostics in VS Code. | Geometric: measured overflow, under-resolved images, layout suggestions, --json. build writes no file while validation holds an error, short of an explicit --force. |
| Licence and cost | MIT. Free. No watermark, no paid tier. | MIT. Free. No watermark, no paid tier. |
| Maturity | Large and active. 827,114 VS Code installs, thousands of GitHub stars, releases within the fortnight before this check. | Young, one maintainer, no comparable adoption or third-party ecosystem. |
Run the comparison yourself
This is the one comparison where neither tool picks the terrain, because Lutrin reads Marp decks. Take a real Marp deck of your own and produce three files from it:
marp --pptx deck.md -o marp-default.pptx
marp --pptx --pptx-editable deck.md -o marp-editable.pptx
npx lutrin build deck.md -o lutrin.pptx # add `marp: true` to the frontmatter
Open all three in PowerPoint and click a heading. In the first you select a full-slide picture. In the third you select the heading, retype it, drag a table cell, and the fonts came with the file. Open the second one too, and be fair about it: Marp's editable export does give you selectable text — the difference is what it costs to get there, and how faithfully the design survives.
Then run the test that cuts the other way. The Marp HTML will look
exactly like your CSS said it should. The Lutrin output will look like
Lutrin: different spacing, and your theme:,
style: and per-slide header: directives all
reported as MARP_DIRECTIVE_IGNORED. If that is a deal
breaker, you have your answer, and it took ten minutes.
Every claim about Marp on this page was checked against Marp's own current documentation and repositories on 2026-07-30, against Marp CLI 4.5.0 (released 2026-07-17), Marp Core 4.4.0 and Marp for VS Code 3.6.0. Marp is actively developed and some of this will age; if you find a statement here that has stopped being true, tell us and it gets fixed. Sources: marp.app, the Marpit theme documentation, the Marp CLI README, the VS Code Marketplace listing.