Using Git(Hub) as the backend for this blog

  • Date: March 8, 2025

The website you're viewing here is a blog in every classic sense. It's just a fancy interface that renders a bunch of markdown content under the hood. It's a custom website that I've built. For me, one of the most important features of a blog is the ability to have drafts or unpublished posts. I also want the ability to write these posts from a nice editor in the browser, on the go (vs. only writing on a specific local machine). All of this adds up to a bunch of feature that I did't want to build nor maintain:

  • Security & authorization into the admin portal
  • The admin interface, with a nice syntax-highlighted editor
  • The diff feature to show before & after side by side
  • Previewing draft changes
  • Then the actual draft & writing features themselves.
  • Database management, backup, etc.

These aren't hard features to build, and I learned a lot building them. After a while, the maintenance got tedious, and I guess I got lazy.

I always thought GitHub's code editor and file editor was quite nice, and of course Git's sole purpose in life is to keep versions. So I decided to abandon my custom admin portal, my database schema, and just use Git(Hub).

How it works

At a high level, it's really nothing novel:

  • By default, the website renders content from the main branch. This is what most visitors would see.
  • New posts and drafts are on a different branch. Small changes like fixing typo go straight to the main branch.
  • I make all my edits using GitHub's nice web editor
  • To view a specific revision of the website, I just pass that to the URL. This is how I can preview the website before things get merged back to main.

Behind the scene

A few things behind the scene need to happen to make all that working:

  • The website has a background service that periodically update the main branch
  • A webhook from GitHub to let the website know that it needs to fetch new commits (for preview)
  • I don't have a database anymore and the entire blog is just a few dozen flat files. This means the index page needs to scan through all the files to read their header data every time. Easy enough with some in-memory caching.

Overall, I'm happy with this setup; not having to maintain all the features I listed above.