Self-hosted · ActivityPub · AGPL-3.0

Your blog is a folder of Markdown files

Madblog is a self-hosted blogging platform and Web framework that runs straight from a directory of .md files. No database, no lock-in — and the open Web's protocols wired in by default.

Free and open source · Python & Flask · Docker or pip

The Madblog home page on desktop: a header with navigation, a grid of article cards with cover images, and aggregated external feed entries
The Madblog home page on mobile: article cards in a single column with a compact header
Markdown, not a CMS

Your content is text. Text is forever.

Point Madblog at a folder of Markdown files — an Obsidian vault, a Nextcloud Notes folder, a git clone, a directory synced over SyncThing — and it becomes a blog. There is no database to back up, no export to request, no format to migrate away from.

  • No database required — just a folder with your Markdown files. Editing a post is as simple as editing a file on your server
  • YAML front matter for titles, descriptions, dates, authors and tags — metadata lives in the file, not in a CMS database
  • Folders are categories — nested directories become navigable sections, each with its own index page and feeds
  • View modes for every taste — card grid, compact list or a full WordPress-style scrolling view
An article page on desktop: rendered Markdown with headings, lists, images and a threaded comments section at the bottom
An article page on mobile: the same rendered post in a single column with reactions and replies below
Federation & the open web

Your blog joins the conversation

This isn't a static site generator that merely looks indie. Madblog speaks the protocols that make the web social — so comments land on your site, not on someone else's platform.

  • ActivityPub federation — your blog gets an actor like @blog@example.com. Mastodon users can follow it, reply to it and boost it
  • Mastodon-compatible API — a sensible implementation of the Mastodon client API comes built in
  • Webmentions in both directions — get notified when blogs link your posts, and ping the sources you link to
  • Author replies & reactions — respond to mentions as plain Markdown files under replies/, threaded inline on the post
The guestbook page on desktop: a registry of mentions and interactions collected from across the web, rendered as threaded replies
The guestbook page on mobile: mentions from other sites in a single column
Rendering & syndication

Serious output from plain text

Madblog renders your Markdown on the server — no JavaScript framework, no build step. Technical posts, diagrams and feeds all come out of the same file.

  • LaTeX equations rendered to images with caching — inline and display math just work
  • Mermaid diagrams compiled to inline SVG via mermaid-cli or npx
  • RSS 2.0 & Atom feeds for the blog, every folder, tag and the guestbook
  • Rich link previews via OpenGraph, plus a PWA manifest for installable blogs
A technical article on desktop showing rendered LaTeX equations and a Mermaid diagram inline with the text
The same technical article on mobile with equations and diagram reflowed to the narrow column
And there's more

A small codebase with surprising depth

Everything below is a config flag away — the unglamorous pieces are already where they should be.

Guestbook mode

A dedicated page aggregates public mentions from Webmentions and ActivityPub into a single guest registry for your site.

Aggregator mode

Render external RSS or Atom feeds directly in your blog — great for affiliated blogs or a self-hosted news reader.

Flexible moderation

Blocklist or allowlist mode with rules on domains, usernames and URLs — regular expressions supported.

Visibility controls

Per-post visibility — public, unlisted or replies-only — so you decide what federates and what stays home.

Tags & categories

Hashtags in front matter or inline in the body build a tag index; filesystem folders give you hierarchical sections.

Email notifications

Optional SMTP notifications when new Webmentions or ActivityPub interactions arrive on your posts.

Installable PWA

A web app manifest and service worker turn any Madblog site into an installable app with offline support.

Env-var configuration

Every option in config.yaml is also a MADBLOG_* environment variable — twelve-factor friendly.

How it compares

Federated blogging, minus the machinery

Madblog trades accounts, databases and plugin ecosystems for plain files and sensible defaults — here's how it stacks up against the other self-hosted options in the space.

Feature Madblog WriteFreely Plume WordPress
📝 Content storage Markdown files on disk — no database Database (SQLite/MySQL) via web editor Database (Postgres/SQLite) via web editor Database (MySQL) via block editor
🧰 Publishing flow Edit files directly — Obsidian, Nextcloud, git, SyncThing Browser editor with autosave Browser editor + media gallery Browser editor + media library
⚙️ Runtime Python/Flask — pip or sub-100 MB Docker Go single binary Rust + Diesel (effectively unmaintained) PHP + MySQL
👥 Multi-author Single blog, single author Multi-user, multiple blogs per account Multi-user, collaborative blogs Full roles, teams, multisite
📣 ActivityPub Articles, follows, and bidirectional mentions, replies, likes/shares/quotes — plus a Mastodon-compatible API Posts and blogs federate; it can receive likes/boosts; replies not rendered yet Articles, comments, likes and reshares federate Via official plugin — publishing and interactions
🔗 Webmentions Bidirectional, built in — — Via plugin
💬 On-page discussions Threaded reactions combining Webmentions, AP interactions and Markdown author replies None on-page — planned as separate Remark.as add-on Native comments, federated Native comments + plugins
🧮 Rich content LaTeX equations, syntax highlighting and Mermaid diagrams, rendered server-side Markdown basics Markdown extensions + syntax highlighting Via plugins/theme
🗂️ Organization Folders as sections, tags, per-folder feeds, tag index Hashtags only Tags + built-in full-text search Categories, tags, menus, search
🛡️ Moderation Blocklist/allowlist rules on domains, users, URLs — regex supported Basic instance admin Instance admin Plugin-dependent
📡 Extras Guestbook mode, RSS/Atom aggregator, visibility levels, PWA, email notifications RSS, SEO, i18n — minimal by design Media gallery, full-text search, templates Everything — at the cost of complexity
📦 Status Actively maintained Actively maintained Sparsely maintained Very active core; federation via plugins
Self-host

Your own corner of the web in minutes

A single pip install or a sub-100 MB Docker image brings up the whole blog — rendering, feeds, federation and all.

🐍  pip
# Everything but LaTeX & Mermaid
pip install madblog

# Point it at your Markdown folder
madblog /path/to/your/content

# Or serve it under gunicorn
MADBLOG_CONFIG=/etc/madblog/config.yaml \
  gunicorn --preload -w 8 -b 127.0.0.1:8000 \
  madblog.uwsgi /path/to/your/content
🐳  Docker
# Minimal image (<100 MB) from Quay
docker pull quay.io/blacklight/madblog

docker run --rm -it -p 8000:8000 \
  -v /path/to/config.yaml:/etc/madblog/config.yaml \
  -v /path/to/content:/data \
  quay.io/blacklight/madblog

# Then open http://localhost:8000

Madblog is free software, released under the AGPL-3.0 license. Hack on it, run it, federate it.