One of my earlier posts on this blog talked about the infrastructure of the site: On Blogging. In it I detailed the tech stack I used as well as hosting services.

TL;DR: The blog is hosted on Github Pages, is built using Jekyll, and posts are added by committing them (in Markdown format) directly to the main branch of the blog repo.

Last week I was reading a blog from Simon Willison and one of his pages caught my eye: Today I Learned. His TIL page lists some little snippets of information that are smaller than a traditional blog post and function as a sort of stream-of-consciousness engineering notebook about the things he’s learned. It was really cool to read, so I wanted to build my own version into this blog.

Limitations of Jekyll

If you’re unfamiliar with Jekyll or Github Pages, the setup I’m using is basically just a static site. The commit history is pulling double duty here to give me a version history for the posts I make, but there is no database backing my blog to render dynamic content. Anything I chuck into a _posts directory in my blog repo will attempt to get rendered as a full size post. Attaching a database is maybe possible, but for my purposes infeasible.

There are ways to work around that, of course. I could create a new microblog template and route that would render the smaller content that I’m interested in, but it leaves a weird problem. When writing these blog posts I really need to have access to git, the repository should be cloned, dependencies installed, and, ideally, a local Jekyll server should be running to preview all the content.

That’s… not exactly portable.

The Workaround

The approach I chose is considerably more straightforward – a microblogging API that the front end of my Jekyll blog can hit to render dynamic content.

I threw together a Rails 7 app running on latest Ruby (3.1.2 at time of writing) with a simple Post model with a few utility routes to create and view microblog posts. It’s hosted on Heroku (hence the “free” in the title). Creation is password-protected with HTTP basic authorization, which is enough for how simple this is.

This is what allows the great portability. Since it’s an API, anything that can make a network request (with the correct credentials) can build a new microblog post. I could end up writing a tiny microblog UI to sit on top of this, or, if I’m in really dire straights, I could just cURL it straight to my API.

The Frontend

Now that I have a simple API for my posts, I need to render them in my blog. Adding a flavor-of-the-month Javascript frontend library is maybe possible on Github pages, but in this case, just isn’t worth it.

The entire JS file that drives the microblog view is 118 lines.

There’s 3 parts to this, roughly splitting the file into thirds:

  • A regex parser for the Markdown content (i.e. [Link Text](http://localhost) is converted to the appropriate <a href="http://localhost>Link Text</a>)
  • 2 network requests – one fetches the entire list of posts, the other fetches a single post
  • HTML generator for building the structures generated by the first two items

Right now, supported Markdown is inline code (single backticks), code blocks (triple backticks), and links, like shown above. That’s really all I need for short-form content.

The Downsides

Because this is all dynamic content that’s handled via Javascript, there’s no physical routes that tie the posts from my API to the Jekyll blog. You couldn’t, for instance:


The site simply won’t know how to resolve that path.

The other problem I ran into is the free tier of Heroku (again, because I’m cheap, and this toy is more for me than anything). Heroku automatically spins down web dynos when inactive unless you pay per month. Spooling up another instance takes a few seconds, so there’s a little bit of lag unless the server is already warm when someone tries to hit it.

There’s also a limit on how many hours the dyno can be working per month, but at the current traffic levels, there’s no way it’ll ever bump into that limit.

Both of these are a small price to pay for a free microblog.

Wrap Up

Check out the microblog at!

That’s all for now. Thanks for reading!