# Marp CLI: Markdown slide decks as HTML, PDF, PPTX and images

> Marp CLI turns Marp or Marpit Markdown into static HTML, PDF, PowerPoint and image files. It is a good fit for engineers who want decks in version control, but any PDF, PPTX or image output depends on a separately installed browser.

**marp-team/marp-cli** — A CLI interface for Marp and Marpit based converters

- Repository: https://github.com/marp-team/marp-cli
- Stars: 3,844 · Forks: 194
- Language: TypeScript
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/marp-team-marp-cli

## What Marp CLI solves, and who it is for

The problem is that slide decks are usually trapped in a binary file. A .pptx cannot be reviewed in a pull request, diffed line by line, or generated by a build script. Marp CLI is the command line front end for Marp and for any converter built on the Marpit framework, and it converts Marp or Marpit Markdown into static HTML and CSS, PDF, PowerPoint documents, and image files. The README describes it as "a CLI interface, for Marp ... and any slide deck converter based on Marpit framework."

That places the audience narrowly. If you already write documentation in Markdown and want the same authoring model for talks, this fits. If you want a tool that a non-technical colleague can open and drag slides around in, it does not. The output is generated from text, so the text is the source of truth, and the repository is the storage layer. The topics on the repository (cli, deck, markdown, marp, marpit, presentation, slides) match that framing.

The project is written in TypeScript and published under the MIT licence, with the npm package named @marp-team/marp-cli and the installed binary named marp. The repository was last pushed on 2026-09-08, and the most recent release listed is v4.5.1 from 2026-09-06.

## How conversion actually works: browser as the rendering backend

The architecture has one detail that shapes everything else: HTML conversion is pure Node.js, while PDF, PPTX and image conversion go through a real browser. The README states plainly that you have to install Google Chrome, Microsoft Edge, or Mozilla Firefox to convert a deck into PDF, PPTX, and images, and it marks those conversions with a globe icon throughout the usage section.

So the data flow is: Marp CLI parses the Markdown with the Marp or Marpit engine, produces HTML and CSS, and then, for the binary formats, drives a headless browser to render and print that HTML. That is why the README tells you to update your browser to the latest version when an unexpected conversion problem occurs. It also explains the browser options section and the CHROME_PATH environment variable visible in the Dockerfile, which points at a Chromium binary installed through Playwright rather than Puppeteer, because the Dockerfile comment says Puppeteer does not provide an ARM64 build.

A practical consequence: the HTML path has a much smaller dependency surface than the PDF path. A container or CI job that only emits HTML needs Node.js and nothing else. The moment you add --pdf, you have added a browser to your build environment, and browser versions become part of your reproducibility story.

## Installing Marp CLI and converting your first deck

The fastest route is npx, which needs no install at all. The README calls npx the best way to use the latest Marp CLI for one-shot conversion, and it requires Node.js v18 and later, which matches the engines field in package.json.

```bash
npx @marp-team/marp-cli@latest slide-deck.md
```

With a file named slide-deck.md in the current directory, the README says the converted slide-deck.html is written to the same directory. If you want a different name or location, use the output option.

```bash
npx @marp-team/marp-cli@latest slide-deck.md -o output.html
```

For a PDF, pass --pdf, or let the output extension decide. Both forms below appear in the README, and both require one of the supported browsers to be installed.

```bash
npx @marp-team/marp-cli@latest slide-deck.md --pdf
npx @marp-team/marp-cli@latest slide-deck.md -o output.pdf
```

If you would rather install it into a project and pin the version, the README recommends a local install, which puts the marp command in npm-scripts and under npx marp.

```bash
npm install --save-dev @marp-team/marp-cli
```

Package managers are also covered, with the caveat that the manifests are community maintained rather than maintained by the Marp team: brew install marp-cli on macOS and Linux, and scoop install marp on Windows. For a machine without Node.js or Chrome, the README points at the official container images, marpteam/marp-cli on Docker Hub and ghcr.io/marp-team/marp-cli on the GitHub Container Registry, and at standalone binaries for Linux, macOS (Apple Silicon) and Windows that bundle a Node.js binary.

Two more modes are worth knowing before you write any tooling. Watch mode re-converts on change, and server mode serves a directory.

```bash
npx @marp-team/marp-cli@latest -w slide-deck.md
npx @marp-team/marp-cli@latest -s ./slides
```

One constraint to internalise early: when you pass multiple paths, directories or glob patterns, the README says the --output option cannot be used. If you need to preserve the source directory structure in the output, the --input-dir (-I) option exists, and --output then names the output directory instead of a file.

## PDF and PPTX output options, and where the documentation thins out

Two PDF-specific flags are documented. --pdf-notes adds PDF note annotations to the lower left of a slide page when that page has Marpit presenter notes, and --pdf-outlines adds PDF outlines or bookmarks. The outlines are built from slide pages and Markdown headings by default, and you can suppress either source with --pdf-outlines.pages=false or --pdf-outlines.headings=false.

That is a sensible design: outlines derived from headings give a reader a navigable table of contents without the author writing one, and the ability to turn off the page-derived outlines keeps decks that are mostly one heading per slide from producing a redundant tree. The trade-off is that the flag is a nested option rather than a separate switch, which is easy to mistype in a Makefile.

Where the README is thin is error handling. It says to update your browser when a conversion problem occurs, and to check the browser options, but it does not document exit codes, partial output on failure, or what happens to an already-written file when a later conversion step fails. For a single-file interactive run that hardly matters. For a CI job that converts a directory of decks, you will have to discover the failure behaviour yourself, because the README does not describe it.

## The browser dependency is the real limitation

The clearest case where Marp CLI is the wrong tool is an environment where you cannot install Chrome, Edge or Firefox. The README's important note is unambiguous: any one of those browsers must be installed to convert a slide deck into PDF, PPTX, and image(s). A locked-down build agent, a minimal container you do not control, or a restricted CI image will convert to HTML happily and fail on everything else.

The official container image exists precisely to sidestep that, and reading its Dockerfile shows the cost of doing so. The image installs Chromium via Playwright with system dependencies, symlinks the discovered chrome binary to /usr/local/bin/chrome, sets CHROME_PATH and CHROME_CONFIG_HOME, creates a dedicated marp user, and uses gosu through a docker-entrypoint script to handle the user switch. That is a substantial image, and the Dockerfile even runs marp-cli.js --version at build time to generate a V8 compile cache. If you only need HTML, you are paying for a browser you will never invoke.

A second limitation is subtler. Because PDF rendering is delegated to a browser, the visual result depends on that browser's rendering and print behaviour. The README does not claim pixel-identical output across Chrome, Edge and Firefox, and it does not promise that output is stable across browser versions. It tells you to keep the browser up to date, which is the opposite of pinning. If your workflow requires a byte-stable PDF artefact, that is a genuine risk to weigh.

## Marp CLI compared with Slidev, and Marp compared with Marpit

The most common alternative people weigh against Marp CLI is Slidev. The projects sit on opposite sides of the same decision. Slidev is built around a Vue and Vite toolchain: slides are written in Markdown but the deck is a web application, with components, live coding and a dev server as first-class ideas. Marp CLI is a converter. It takes Markdown in and writes HTML, PDF, PPTX or images out, with no application runtime and no framework to learn beyond the Marp directives and themes. If your goal is a file you can attach to an email or print, the converter model is a better match. If your goal is an interactive web presentation with embedded components, Slidev is aimed at that and Marp CLI is not trying to be.

The Marp versus Marpit distinction is a different axis and is worth getting right before you file a bug. Marp CLI uses @marp-team/marp-core, and the README describes the CLI as an interface for Marp and for any converter based on the Marpit framework. Marpit is the lower-level framework; Marp is the presentation-oriented layer built on it. In practice this means the CLI can drive more than one engine, and a directive or theme feature that exists in Marpit is not automatically part of the Marp experience. When something does not render the way you expect, the first question is which engine you are actually using.

## Maintenance, upgrade cost and the MIT licence

The repository is not archived, and its last push was on 2026-09-08. Releases are frequent rather than annual: v4.4.1 on 2026-07-04, v4.5.0 on 2026-07-17, and v4.5.1 on 2026-09-06. That cadence means a pinned version will fall behind quickly if you care about browser-related fixes, which is exactly the class of bug the README points at when it tells you to update your browser.

The upgrade cost is mostly in the Node.js floor and the browser. package.json declares engines.node as >=18, and the README repeats the v18 requirement. The Dockerfile builds on node:26.8.1-bookworm-slim, so the published image tracks a much newer Node.js than the package minimum. If your CI pins an older Node.js image, the npm package may still install while the container path moves ahead of you.

On licensing: the package declares MIT, and the repository carries a LICENSE file at its root. MIT is permissive and imposes no copyleft obligation on your decks or your build scripts. That is the extent of what the public documentation supports; it is not legal advice, and if you redistribute the container image you should read the licences of the bundled components, including Chromium, yourself.

## Conclusion

Adopt Marp CLI if your decks belong in the same repository as the code and you want HTML, PDF, PPTX or images generated from plain Markdown. Do not adopt it if you need a visual editor, collaborative editing, or a PDF pipeline on a machine where you cannot install Chrome, Edge or Firefox. Before committing to it, verify three things: that Node.js is v18 or later, that a compatible browser is present on every machine and CI runner that will produce PDF, PPTX or images, and that the themes and directives your deck relies on are supported by the Marp or Marpit engine you point the CLI at.

## FAQ

### What is Marp CLI used for?

It converts Marp or Marpit Markdown files into static HTML and CSS, PDF, PowerPoint documents and images. The README describes it as a CLI interface for Marp and for any slide deck converter based on the Marpit framework.

### What are the key differences between Slidev and Marp CLI?

Marp CLI is a converter: Markdown in, HTML, PDF, PPTX or images out, with no application runtime. Slidev is a Vue and Vite based presentation tool, so it targets interactive web decks with components rather than static file conversion. The README describes Marp CLI's role but does not document Slidev's internals.

### How do I export a Marp presentation to PPTX?

Pass the --pptx option, or give the output path a .pptx extension. Either way the README requires Google Chrome, Microsoft Edge or Mozilla Firefox to be installed, because the conversion runs through a browser.

### What are the differences between Marp and Marpit?

Marpit is the framework, and Marp is the presentation layer the CLI uses through @marp-team/marp-core. The README frames Marp CLI as an interface for Marp and for any converter based on Marpit, so the CLI can drive more than one engine.

### How do I install Marp CLI?

Run it without installing via npx @marp-team/marp-cli@latest, install it locally with npm install --save-dev @marp-team/marp-cli, or use brew install marp-cli on macOS and Linux or scoop install marp on Windows. Node.js v18 or later is required for the npm routes, and standalone binaries and container images are also published.

### How do I use Marp CLI?

Pass a Markdown file to the marp command and it writes HTML to the same directory by default; use -o to change the path, --pdf or --pptx for those formats, -w for watch mode, and -s with a directory to serve decks. Note that --output cannot be combined with multiple input paths, directories or glob patterns.

## Sources

- [Issues](https://github.com/marp-team/marp-cli/issues)
- [License: MIT](https://github.com/marp-team/marp-cli/blob/main/LICENSE)
- [marp-team/marp-cli on GitHub](https://github.com/marp-team/marp-cli)
- [README](https://github.com/marp-team/marp-cli/blob/main/README.md)
- [Releases](https://github.com/marp-team/marp-cli/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/marp-team-marp-cli
