Markdown Static Site Generator CLI
Build a static site generator in Go, a small version of Hugo: point it at a folder of Markdown files and it produces a complete, styled HTML website with a shared layout, an index page listing posts newest first, and tag pages. Each Markdown file starts with front matter (title, date, tags and a draft flag), pages are rendered with Go's html/template, and a watch mode rebuilds the site automatically whenever you save a file, with a small local server to preview it. You'll learn walking folders with filepath.WalkDir, converting Markdown to HTML (with blackfriday as the stack suggests, or goldmark, the more actively maintained choice), parsing front matter, html/template layouts, command-line flags, and watching files for changes.
- Estimate
- ~10.5h
- Steps
- 6
- Completed by
- 0
- Proposed by
- codeseed.app
blackfriday or goldmark · html/template · flag · fsnotify
Project roadmap
- 01
Collect the source files
~1.5hCreate a Go module with flags -src, -out, -drafts and -watch (with the flag package). Walk the source folder with filepath.WalkDir, collecting .md files and copying other files (images and CSS) to the output folder unchanged. Check the source folder exists and refuse to use the same folder for output. Done when: running the tool lists the Markdown files and copies static files to the output folder.
- 02
Parse front matter and convert Markdown
~2hSplit each file into front matter (YAML between --- lines, parsed with gopkg.in/yaml.v3) and body, validating that title and date exist and the date parses. Convert the body to HTML with blackfriday or goldmark (with raw HTML disabled). Create a slug for each page from its file name or a slug field, and report duplicate slugs. Done when: each Markdown file becomes a page struct with metadata and HTML, and invalid front matter is reported with the file name.
- 03
Apply a layout template
~2hWrite templates with html/template: a base layout (head, navigation and footer) and a post template, and render each post into out/posts/SLUG/index.html. Mark the converted Markdown as template.HTML so it isn't escaped, while titles and tags are escaped automatically. Skip drafts unless -drafts is set. Done when: every post renders inside the shared layout and opens correctly in a browser.
- 04
Generate the index and tag pages
~1.5hRender an index page listing posts sorted by date (newest first) with their summary, a page per tag listing its posts, and a simple RSS feed. Build everything into a temporary folder and swap it into place at the end, so a failed build never leaves a half-updated site. Done when: the index, tag pages and feed are generated and linked correctly.
- 05
Add watch mode and preview
~2hWith -watch, serve the output folder with http.FileServer on localhost, and watch the source folder with fsnotify, rebuilding (with a short delay to group several quick changes) whenever a file changes, and printing any build errors without stopping. Done when: editing a Markdown file updates the previewed site within a second.
- 06
Test it
~1.5hWrite tests with a temporary source folder: front matter parsing (valid, missing title and bad date), slug generation and duplicates, draft handling, index ordering, escaping of titles, and a full build compared with expected output files (golden files). Done when: go test ./... passes.
Resources
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack