Bliki Phase 1: Building the Core

Phase 1 was about proving the concept: could a static site generator be built as a single Go binary with minimal dependencies, using Markdown files as the source of truth?

The result was bliki — a generator that takes Markdown from a content/ folder, renders it through Goldmark, wraps it in Go templates, and outputs a complete static website in public/.

Project Inception

The first commits laid out the project's goals and architecture. A Go module was initialized at git.mittelab.org/proj/bliki, and the directory structure was defined: cmd/ for CLI commands, internal/ for domain packages, and embed/ for bundled assets.

Key decision: Use Hugo's command naming convention (bliki new site, bliki build) rather than inventing new terminology. Familiar CLI patterns lower the learning curve.

Core Engine

The internal/engine/ package handles the heart of Bliki:

YAML frontmatter was chosen over TOML or JSON for metadata. The go.yaml.in/yaml/v4 library provides clean parsing with type safety. Any unrecognized YAML keys are stored in a Meta map, giving users the freedom to add custom variables without schema changes.

Markdown rendering uses github.com/yuin/goldmark, a CommonMark 0.31.2 compliant parser. Goldmark was chosen over blackfriday for active maintenance and Go module support. Extensions include GFM (GitHub Flavored Markdown), footnotes, and definition lists.

Template rendering leverages Go's html/template package. All .tmpl files in theme/templates/ are parsed into a shared template set, enabling cross-references between layouts and partials. Layouts use {{define}} blocks for inheritance — default.tmpl defines the base structure, and page-specific templates override named blocks.

CLI Architecture

The CLI uses github.com/spf13/cobra for command definitions and github.com/spf13/viper for configuration. Commands follow a verb-noun pattern:

bliki new site ./myblog
bliki new content blog/my-post.md
bliki build

Three core commands emerged:

Configuration is read from bliki.toml (TOML format) with support for BLIKI_* environment variable overrides.

Asset Pipeline

Theme static assets (CSS, JS, images) are copied from theme/ to public/ preserving directory structure. This means theme/css/style.css becomes public/css/style.css automatically.

The embedding system (//go:embed) bundles both the init templates and default theme files into the binary, making bliki fully self-contained.

Design Decisions

Several key choices shaped the early architecture:

  1. html/template over other templating engines — no external runtime, type-safe HTML output, built-in XSS protection
  2. goldmark over blackfriday — active maintenance, pure Go module, extensible
  3. cobra over urfave/cli — better subcommand support, ecosystem integration with viper
  4. TOML for config over YAML — disambiguates config files from content YAML frontmatter
  5. No database, no external services — the entire site is files. Versionable, portable, deployable anywhere

License Migration

Early on, the project moved from per-file copyright headers to a single LICENSE.md file (MIT), following Go project conventions. This simplified maintenance and kept file headers clean.

Test Infrastructure

Tests were organized across packages:

The test suite covers frontmatter parsing, build rendering, template resolution, and nested template layouts.

What's Next

Phase 1 delivered a working static site generator with blogging features — chronological posts, tags, drafts, and theme-based layouts. Phase 2 expanded the scope: making git the source of truth, adding web editing, and enabling collaborative workflows.