moffee turns a markdown file into a paginated, themed slide deck
moffee: Make Markdown Ready to Present
At a glance
- What is it?
- A Python slide maker that reads extended markdown, decides where slides break, arranges elements with a divider syntax, and serves the result live in a browser or exports it to HTML.
- Who is it for?
- Adopt moffee if your slides are prose and lists, if you want the deck in version control as a text file, and if HTML or PDF output is enough for your audience. Do not adopt it if you need an editable PowerPoint file, complex diagrams, or a tool that a team can keep using for years without checking upstream, since the last tagged release is v0.2.7 from 2024-11-22 and the repository has moved on since.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 88 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What moffee decides for you, and what it leaves to you
moffee describes itself in five words, Make Markdown Ready to Present, and the mechanism is a pipeline: a markdown document goes in, a paginated and styled deck comes out. The README states the split of labour plainly. moffee handles layout, pagination and styling, so the author focuses on content, and the syntax is deliberately small, because the stated goal is that there is little to learn.
That framing is the interesting part of the design. Most markdown renderers treat a document as a document. moffee treats it as a sequence of frames, and the interesting engineering is in the decisions it makes on the author's behalf. Slides break on new headings, and when a slide has no title of its own, moffee picks the most suitable title for it from the surrounding context. The README also notes that moffee automatically adjusts element sizes to accommodate large blocks of text or complex illustrations, so an image and a paragraph on the same slide are sized to fit together rather than overflowing.
The author keeps a small set of escape hatches for the cases where the automatic choice is wrong, and the rest of this article is mostly about those. The input dialect is standard markdown plus most of the extended syntax found in Obsidian Flavored Markdown, and the parser dependency list in the packaging metadata names myst-parser and pymdown-extensions for that job, along with the markdown library itself and Jinja2 for templating.
Slide boundaries come from headings, or from a page break marker
A new slide starts when a new heading begins. That is the whole rule, and it means a deck that is written as an ordinary document will paginate in a way that mostly makes sense:
## Page 1
Some text
## Page 2
This sentence will appear on the second slide.The alternative is to take control directly, with a line containing three hyphens forcing a break in the middle of a section:
## Page 1
Text on the first slide
---
Text on the next slide.The README points out the consequence of that, and it is a design decision rather than a bug: the second slide shares the Page 1 title, because moffee selects the most suitable title for each slide and the surrounding content did not offer a better one. If you want a specific title on a manually broken slide, give it a heading.
That behaviour has a practical consequence for authoring. Writing for moffee means deciding, per slide, whether you want the automatic context title or an explicit one, and it means the number of level 2 headings in your document is the number of slides. A long document with many small headings becomes a long deck, and a document with one big heading becomes a single frame unless you add breaks. moffee does not read intent about slide density, and it does not split a wall of prose across frames for you, since the pagination is driven by structure rather than by length.
Dividers arrange elements inside a slide, with a fixed precedence
Inside a slide, moffee offers two divider characters, and the rule between them is stated in one sentence: === places elements vertically and takes precedence over <->. The horizontal divider is written as a line containing an arrow between angle brackets:
Text on the left.
<->
The vertical divider is three equals signs, and the README shows it used to build a stacked arrangement, with a horizontal split nested inside it:
Top bun
===
Patty on the left
<->
Lettuce on the right
===
Bottom bunThe precedence rule is what makes that nested example unambiguous. When both dividers could apply, the vertical one wins, so the structure reads top to bottom with a horizontal pair inside the middle band. The README also describes the intended use, which is to organise text and images with dividers, and it notes that the same syntax can trigger a page break when the three hyphens form is used instead.
The size of each element is not something you write down. moffee adjusts element sizes automatically to fit large text blocks or complex illustrations, so the layout work is a matter of choosing the arrangement, not of tuning dimensions.
Front matter, built in themes and any CSS property
Document level behaviour is set in YAML front matter, and the README calls out the options people actually use. The theme picks one of the built in designs, layout chooses the HTML template, resource_dir sets the base for relative URLs, and aspect_ratio fixes the shape of the frame:
---
theme: default # Other available themes are "beam", "robo", "blue" and "gaia"
layout: content # HTML template. Use "centered" for centered alignment.
resource_dir: "." # Relative URLs are based on this directory.
aspect_ratio: "16:9" # Aspect ratio of the slides
---The five themes named in the README are default, beam, robo, blue and gaia, and the documentation site links to a page that shows them. The layout value is described as an HTML template, with centered offered as the alternative to content.
The second half of the styling story is that the front matter is not limited to a fixed set of keys. Any CSS property can be set there, and the README's example is a dark background with white text for every slide:
---
layout: content
background-color: darkgray
color: white
---For one slide rather than all of them, moffee has local style decorators written as @(property=value). The example sets a layout and a background image for a single slide:
# A refined landing page
Our journey begins here
@(layout=content, background-image='url("https://placehold.co/600x400")')The decorator syntax is what lets one document mix a normal content slide with a landing slide, without a separate file or a theme fork. The cost is that the styling vocabulary is CSS rather than something designed for slides, so a designer will end up writing CSS in YAML front matter, and the README points to the configuration documentation for the full option list rather than enumerating it.
Two output paths: a live server and an HTML export
The command line has two entry points for the same document. The first starts a live web interface that updates as you type, which is what the README advertises as the reason to use the tool, since you can start a slideshow or export the result from the same place:
moffee live example.md # launch a server
# or
moffee make example.md -o output_html/ # export to HTMLThe live mode is backed by a livereload dependency in the packaging metadata, and the mention of live reload in the project dependencies is consistent with a preview that refreshes when the file changes. The export path writes into a directory you name, and the command is called make rather than build or export, which is a small thing but tells you the output is a generated directory rather than a single file.
The project description also mentions exporting to PDF, and the README does not give a separate PDF command next to the live and make commands. The most likely route, given the HTML output, is printing or exporting the served deck from a browser, and if PDF is a hard requirement you should check that path against your own deck rather than assume a dedicated command exists. That gap between the summary sentence and the documented commands is worth a minute of your own testing.
Installation is the simplest part. The project is published on PyPI and the README recommends pipx, with a plain pip install as the alternative, and it points to a documentation page for step by step instructions:
Packaging details and the shape of the dependency set
The packaging metadata describes a project with a single console script and a moderate dependency list. The entry point is moffee, mapped to moffee.cli:cli, so the tool is a Click application, and the project requires Python 3.10 or newer. The runtime dependencies are jinja2 for templating, markdown for the core parsing, pymdown-extensions and myst-parser for the extended syntax, pyyaml for front matter, click for the command line, beautifulsoup4 for HTML work and livereload for the live preview.
That is a small, well understood set, and each one maps to a job you can see in the README. The build backend is hatchling, and the development extras are a conventional test and lint toolchain: pytest, flake8 with a maximum complexity of 10, black, pre-commit, mkdocs and mkdocs-callouts for the documentation site, plus ipdb and pygments for debugging and highlighting.
The docs are a separate deliverable with their own configuration. There is a mkdocs.yml, a .readthedocs.yaml and a docs directory, and the published site is at moffee.readthedocs.io, with the README linking to pages for installation, syntax, configuration and themes. The project also ships translated READMEs in Spanish, Japanese and Chinese, and a CLAUDE.md file sits next to them, which suggests the repository is set up for assistant tooling as well as human contributors.
Maintenance, licence and the cases moffee does not cover
The licence is MIT, and the packaging metadata repeats it in the project table. The project was created by Wenbo Pan, and the README links the same repository under a different owner name, BMPixel, which is worth noticing because the repository you are reading and the one the badges point to are not the same URL.
The maintenance picture is mixed, and this is the part to weigh. The last push to the repository was on 2026-07-27, so work is still happening, but the newest tagged release is v0.2.7 from 2024-11-22, with v0.2.6 in August 2024 and v0.2.5 the day before it. The version in the packaging metadata is still 0.2.7, which means the released artifact and the repository head are the same version number, so the fixes that landed after November 2024 are only available from the source tree unless a new tag appears. For a tool whose output is a one-off presentation, that gap matters less than it would for a library, but it does mean the pip install path may not include the most recent work.
On the output side, the documented targets are HTML and PDF, and no PowerPoint export is mentioned anywhere in the README. If your organisation requires an editable.pptx that a colleague can change without touching the source, moffee is the wrong tool, and the alternative is a general presentation application where the deck is the artifact rather than a rendering of a text file. The trade is real in both directions: a binary deck is easier to hand to a non technical colleague, while a markdown deck is reviewable in a pull request, diffable, and regenerable.
The other limit is the content model. moffee is a text and image renderer with automatic paging. A diagram, a chart or a table with meaningful structure is not something it describes, and a deck whose value is in the visuals is going to need the visuals produced elsewhere and embedded as images.
Editorial conclusion
Adopt moffee if your slides are prose and lists, if you want the deck in version control as a text file, and if HTML or PDF output is enough for your audience. Do not adopt it if you need an editable PowerPoint file, complex diagrams, or a tool that a team can keep using for years without checking upstream, since the last tagged release is v0.2.7 from 2024-11-22 and the repository has moved on since. Verify first that pipx install moffee gives you the version you expect and that your existing markdown survives the Obsidian flavoured syntax moffee parses, then keep the source deck in the same repository as the rest of your documentation.
Frequently asked questions
How do I install moffee and preview a deck?
The project is published on PyPI and the README recommends pipx install moffee, with pip install moffee as the alternative, and it requires Python 3.10 or newer. Once installed, moffee live example.md starts a live web server for the deck, and moffee make example.md -o output_html/ exports it to HTML.
How do I control slide breaks in moffee?
A new heading starts a new slide, and a line with three hyphens forces a break inside a section. When you break a slide manually it keeps the surrounding title, because moffee picks the most suitable title for each slide from the context, so give a slide its own heading when you want a specific title.
How do I place two elements side by side in moffee?
Use the horizontal divider <-> on its own line between the elements. The vertical divider === stacks elements instead, and it takes precedence over the horizontal one, so the two can be combined for a stacked layout with a horizontal pair inside one band.
How do I change the theme, aspect ratio and background of a moffee deck?
Set them in the YAML front matter of the document. The theme accepts default, beam, robo, blue and gaia, layout selects the HTML template, resource_dir sets the base for relative URLs and aspect_ratio sets the shape of the frame. Any CSS property can also be set there, for example background-color and color for a dark deck.
Can moffee export a PowerPoint file?
The README documents a live web server, an export to HTML, and PDF among the capabilities of the tool, and it does not mention any PowerPoint export. If an editable .pptx is a requirement, a general presentation application is the practical route, since the deck there is the artifact rather than a rendering of a markdown file.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/wbopan-moffee)Was this useful?