When I decided to build my personal website, I considered the usual options—Hugo, Jekyll, Eleventy, Astro. They're all excellent tools. Instead, I decided to write my own.

This post explains the reasoning and what I learned along the way.

The Appeal of Zero Dependencies

Modern web development often involves complex toolchains. A simple static site might pull in dozens of npm packages, each with their own dependencies and update cycles.

For a personal website that I want to maintain for years, I wanted something simpler:

  • No external dependencies to update or audit
  • Complete understanding of how it works
  • Fast builds without complex tooling
  • Easy to modify when needed

What I Actually Needed

The requirements were straightforward:

  1. Write content in Markdown
  2. Apply HTML templates
  3. Generate static files
  4. Deploy to S3/CloudFront

That's it. The core logic fits in a few lines:

html = parse_markdown(content)
page = template.substitute(content=html)
output_path.write_text(page)

The Implementation

The generator is about 200 lines of Python. It includes:

  • A Markdown parser supporting common syntax (headers, lists, code blocks, links)
  • A simple template system using Python's string.Template
  • Incremental builds with file hashing for cache invalidation
  • Front matter parsing for page metadata

Build time for the entire site is around 3 milliseconds.

Writing a Markdown Parser

Parsing Markdown is simpler than it might seem. The core syntax—headers, paragraphs, emphasis, links—can be handled with a straightforward state machine and a few regular expressions.

The tricky parts are edge cases: nested formatting, code blocks containing Markdown-like syntax, and list continuation. For a personal site, handling the common cases well is sufficient.

Lessons Learned

Start with the minimum. I initially planned more features than I needed. Starting simple and adding only what's necessary resulted in cleaner code.

Standard library is capable. Python's string.Template, pathlib, and hashlib covered everything I needed without external packages.

Caching matters. The biggest performance win was skipping unchanged files. Incremental builds are nearly instant.

Should You Do This?

For most people, existing static site generators are the right choice. They're mature, well-documented, and handle edge cases you haven't thought of.

But building your own is a good exercise if you want to:

  • Understand static site generation deeply
  • Have complete control over your toolchain
  • Keep your site simple and maintainable for the long term

The source code is available on GitHub.