marp-cli config, watch mode, server mode and engines
Past the first marp deck.md --pdf, marp-cli has four features that make it a course workflow: a config file (.marprc or marp.config.js) holding the theme set, HTML setting and options so every command is short; --watch to rebuild on save; --server to serve a folder of decks; and --engine for markdown-it plugins. This guide shows each with the exact file or flag, then a Makefile.
The config file
marp-cli reads marp.config.js (also .mjs/.cjs), .marprc (JSON or YAML), or a marp key in package.json, from the current folder. For a course:
# .marprc.yml
themeSet: ./themes
allowLocalFiles: true
html: true
pdfOutlines: true
options:
emoji:
unicode: false
Then marp slides/week-05.md --pdf uses the themes, allows local images, enables HTML and adds PDF bookmarks without repeating the flags. options are Marp Core constructor options (math, emoji, and so on). A different config for a different job: marp -c student.yml ….
Watch mode
marp -w slides/week-05.md
Rebuilds the HTML on every save. With --pdf it rebuilds the PDF, which is slower but shows the real page breaks. Pair it with a browser tab on the output file and reload, or use the preview window:
marp -p slides/week-05.md
--preview opens a window that reloads on change and can be presented from as an immersive window (it is not available in the Docker image).
Server mode
marp -s slides/
Serves the folder on a local port: open the URL, click a deck, and it converts on request; edits show on reload. Query parameters pick a format (?pdf, ?pptx). It is the quickest way to browse a term's decks without building anything, and a reasonable "presentation server" for a lab machine.
Whole-folder conversion
marp -I slides -o dist --pdf
--input-dir converts every Markdown file under slides, keeping the structure, into dist. This is the CI command; see publishing on GitHub Pages.
Engines
An engine file customises the Marp instance: extra markdown-it plugins, custom directives, changed rendering.
// engine.mjs
export default ({ marp }) => marp.use(myMarkdownItPlugin);
marp --engine ./engine.mjs deck.md
Two engines on this site that were tested with marp-cli 4.5: one that renders Mermaid diagrams and one that drops slides marked hidden. Put engine: ./engine.mjs in the config file to use one by default.
A course Makefile
SLIDES := $(wildcard slides/*.md)
PDFS := $(patsubst slides/%.md,dist/%.pdf,$(SLIDES))
HTMLS := $(patsubst slides/%.md,dist/%.html,$(SLIDES))
all: $(PDFS) $(HTMLS)
dist/%.pdf: slides/%.md themes/*.css
marp $< -o $@ --pdf
dist/%.html: slides/%.md themes/*.css
marp $< -o $@
watch:
marp -w -I slides -o dist
serve:
marp -s slides
clean:
rm -rf dist
With the config file holding the flags, the recipes stay one line each, and make only rebuilds the decks that changed.
The other flags worth knowing
--notesexports the speaker notes as text;--pdf-notesputs them in the PDF as annotations.--images pngrenders one PNG per slide;--image pngonly the title slide (a thumbnail for a course page).--themeoverrides the deck's theme by name or file;--theme-setloads a folder of themes.--bespoke.progressadds a progress bar to the HTML;--bespoke.transition=falseturns transitions off.- Piped input:
cat deck.md | marp -o out.pdf --pdfreads Markdown from standard input, which is how a script can feed a generated deck in (and why marp-cli waits when nothing is piped: give it a file or< /dev/null).
The full list is marp --help; the cheat sheet has the ones a slide author uses.
FAQ
Where does marp-cli look for a config file?
marp.config.js (.mjs, .cjs), .marprc (JSON or YAML) or the marp key in package.json, in the current directory; -c path names another.
How do I make marp-cli rebuild on save?
marp -w deck.md (watch), or marp -p deck.md for a preview window that reloads.
What does marp-cli server mode do?
marp -s folder/ serves the folder; each Markdown file converts on request in the browser, with ?pdf and ?pptx for other formats.
How do I convert all decks in a folder?
marp -I slides -o dist --pdf, which keeps the folder structure in dist.