A zero-config static site generator for dev blogs


Install md2blog

Option A: pre-built executable

First, download the appropriate zip file for your platform from the md2blog releases page. Then unzip the binary, and place it somewhere convenient (e.g. somewhere in PATH).

Option B: install script using Deno

Alternatively, and only if you have Deno and are familiar with it, install the md2blog script (with desired permissions) using deno install:

deno install -r -f --allow-read --allow-write --allow-net=localhost

Note: -r and -f are used to replace any previous installation of md2blog.

Create site from template

After ensuring you can run md2blog (e.g. with md2blog --help), it's time to create your site (if md2blog doesn't run, check the FAQ for likely problems).

You can start from scratch (using the information on the rest of this page) or continue reading this section to learn how to use the md2blog-template-site repository.

Download the zip file of the template and extract the files somewhere.

Customize the site

The directory structure for the template site is explained later.

Here are some recommended first steps:

  1. Update content/site.json and edit the title, description, and footer.text properties (and optionally add a url property)
  2. Create directories under content/posts/ for categories
  3. Create posts as *.md Markdown files under the category directories, e.g. content/posts/misc/ (see below for the metadata format)

Build and view the site

To build and test the site locally (with automatic reloading), run:

md2blog --clean --serve

And open a browser to the "localhost" URL that is written to the console. You can kill the server with Ctrl+C.

More details on building and testing locally are below.

Read on for more information

The rest of this page contains more detailed information on how to use md2blog. Feel free to skim it or just use it for reference, as needed.

Additional resources:


md2blog reads input from a single input directory (content/, by default) and writes a static site to an output directory (out/, by default).

The input directory contains site metadata, posts, pages, and static assets:

Posts and pages are authored in plain text using Markdown (.md extension), with YAML front matter for specifying metadata (such as the date of the post).

Directory structure

Example content

See the template repository for a complete example.


Here's an example site.json file:

    "$schema": "",
    "title": "My dev blog",
    "url": "",
    "description": "A very good dev blog indeed",
    "footer": {
        "text": "Optional copyright notice goes here"

Note that the (optional) $schema property is not used by md2blog, but is instead used by some editors (e.g. VS Code) to support contextual hints and auto-complete based on the site.json JSON schema.

Schema (official link here):

Field Type Required? Note
title string Required
url string Recommended
description string Optional Used in meta tag and as the default subtitle
colors object Optional See theme FAQ for details
header.text string Optional Overrides the default subtitle
header.links object Optional Site-wide navigation links (more details here)
footer.text string Optional Footer text added to all pages of the site (recommended for adding a copyright notice)

Note that the site will generally work without specifying a URL, but the Atom feed may not work in all feed readers because it will be forced to use relative links instead of absolute URLs.


Posts are written in Markdown and use YAML for front matter (fenced above and below by three hyphens: ---).

Front matter

Here's an example showing all of the supported YAML front matter properties (title and date are required):

title: First post
date: 2021-10-26
description: First post on my blog, with a relative link.
keywords: [additional-tag]
draft: true
(Markdown content follows...)


Field Type Required? Note
title string Required
date YYYY-MM-DD Required Format: YYYY-MM-DD
description string Optional This text is displayed on index pages
keywords string[] Optional Additional tags for categorizing the post
draft Boolean Optional If true, the post will only be built if --drafts was specified on the command line


Here's example Markdown content, demonstrating relative links (these links get translated to the corresponding HTML files and the links are checked at build time; they also work in the VS Code and GitHub Markdown previewers):

# Relative links
Here's a relative link to another post in this category: [link](!

And here's one to another category, with an anchor: [link 2](../category2/

# Image
Here's an image:

Finally, here is an example of a code block (specifying the language is recommended, but optional):

# Code block
Here's some code:

const add = (a, b) => a + b;

Building and testing locally

To build the site locally, use the following command (note: --clean is optional):

md2blog --clean

The file will be written to the out/ directory.

To test the site, simply open out/index.html directly from the file system.

Local web server with automatic reloading

You can also test using a local web server that will automatically regenerate and reload pages when you save content files to disk using this command:

md2blog --serve

Command line options

For more details on command line options, see this FAQ entry.


md2blog doesn't have any built-in support for publishing sites, but all that's required is copying everything from out/ to your web root.

Publishing to GitHub pages

If you're planning to publish to GitHub Pages, here's an example:

  1. Build your site with md2blog --clean
  2. Initialize Git in out/ and upload for the first time:
cd out
git init .
git checkout -B web
git remote add origin <your remote repository>
git add .
git commit -m "Upload site"
git push -u origin web
cd ..

To update your site in the future:

md2blog --clean
cd out
git add .
git commit -m "Update site"
git push
cd ..

Finally, set up GitHub Pages on your repository to publish from the appropriate branch/directory (the "web" branch, in this example).

Note that if you want to use a custom domain, just follow GitHub's custom domain directions and then plop your CNAME file in the content/ directory prior to building your site.

Now go build your dev blog!

That's all there is to md2blog. There's no need to worry about themes or plugins. Just start writing!

If you have additional questions, consult the FAQ. If you don't see an answer there, feel free to post in the md2blog discussion board (or report an issue, if something is broken).