Miscellaneous bits and bobs from the tech world

This blog is built atop of GitHub Gist...

9/17/2021, 2:52:14 PM

In case you were wondering, this blog is:

I managed to stand up a minimal version of this (sans styling) in a single afternoon1. Here's how it works, and some caveats.

Using Github Gist as a data store

Using Gist as a data store is not a novel idea, I've seen it reproduced a number of times by other people. It's free, there's an API, and I don't have to worry about backups, since the service itself can be considered an off-site backup separate from the web server serving the blog.

They have a free API that returns any user's public gists

ww9 suggested in his guide that appending #blog to your gist title would allow it to be filterable – N.B. this ended up not being the case, but I still appended the tag and did the filtering from within the Node app itself.

I used node-fetch to retrieve the gists, and stored the result in-memory, along with the ETag present in the response header.

Every time the page loads, I send a HEAD request to that same URL, and compare ETags. If there is a mismatch, I update the gists stored in-memory. I didn't want to be a bad consumer (of a free API, no less!) and continually hit the route on each page load, if the data hadn't changed.


  • Instant updates – the moment a gist is saved (or edited), the ETag returned by GitHub will be different. Accessing the blog immediately afterwards will pull a fresh set of gists.
  • Someone else already handled the post editor, storage, image upload support, and backups, all I had to build was a thin frontend to access them.
  • GitHub can probably preserve my gists for all eternity. The same cannot be said of my DigitalOcean droplets. Should something happen to the server, a new frontend can be spun up with minimal headache.
  • Built-in "drafts" support – Gists can either be public or secret. By publishing a secret gist, it is essentially a draft, because it will not be added to the API call to retrieve a user's public gists.
  • Revisions and rollbacks supported – changes to gists are commits, and you are able to roll back to an earlier version if necessary


So far so good, but some things I have noticed:

  • A gist is created once (and updated over time), but it is not possible to backdate a gist. Migrating blog posts with the original timestamp is out of the question, as the created_at date returned by GitHub will always be the date the Gist was created.
  • The default API returns a maximum of 30 gists. A per_page argument increases this to 100, but after that, I will have to build additional logic to handle additional pages2


1 This wasn't meant to be a humblebrag. Between my 2-year-old toddler and a newborn, I needed to move fast or this wasn't getting off the ground at all! It looked ugly, but it did its job.

2 sigh... even in my hobby projects, feature creep finds a way.