A Small Survey of Static Site Generators

March 1, 2021 | 10 min. read


I've had something of an unfortunate series of expieriences when it comes to the technology that powers this site. Despite being a simple collection of static text and images, I've never been able to settle on a good way to generate posts in a way I'm satisfied with. To purists or those that think web development is bloated garbage for morons, serving static documents might seem like a solved problem - and they'd largely be correct (about the problem, not the gatekeeping!). Basically every tool I've used has looked identical to end users, with the only real difference being the developer experience. This post is essentially a short history of the various tools I've used to build this site.

Old-School

When I first started this site, I was just writing raw HTML documents in a GitHub Pages repo. It was nice to not worry about deployment or server management, but I didn't really feel a sense of ownership when all of my writing was under a .github.io domain. With GitHub housing all my code (and that of all my other projects) and also serving it, I was beginning to get a little wary of overreliance on any one company/service. There's also not any easy way to hide things in the repo that you dont want served as part of the Pages site - everything is exposed as if it were a directory on a server. Writing every page by hand as HTML was also a pain in the ass. Replicating layouts across pages was very anti-DRY and error-prone, and having to refresh and visually inspect every page for missing tags or weird rendering bugs was time consuming.

Eventually, I bought this domain migrated the site to a VPS along with some other stuff I wanted to run like my urbit instance and some scripts/bots I need up 24/7. I now had to manage my own server and run a quick scp -r blog/ janissary.xyz:/var/www/html on every update, but it was fun to LARP as a greybeard webmaster for a bit. I still had all the headaches when it came to writing the content however, so I started looking for an alternative.

Jekyll

A lot of the other blogs I read have a little "Made with Jekyll" stamp at the bottom, so I decided to check that out. At first it seemed like everything I was looking for - a nice templating language similar to ones I'd used in Flask and Laravel, a hot-reload development server, and plugins for things like RSS. This worked out alright and was certainly better than my previous setup, but had some headaches of its own. Jekyll is incredibly opinionated, and assumes that your site is laid out in one very specific way. For example, it assumes every post is in the local _posts directory and creates a URL schema for posts according to publish dates; a post published on March 5, 2021 would be at available blog.com/2021/3/5/post.html. I really don't like this clutter in the URL bar, and it's kind of pointless if you have only one post on any given month or year. Changing this requires putting every post in a directory other than _posts, writing a bunch of YAML config files, and other various fiddling (the RSS plugin I found wouldn't even work if you changed things too much). Even on my very small blog, the development server also began to chug on big posts with really frequent changes. It was soon time to look for something else again.

Hugo

I recently came across Jamstack and although I'm not sold on the architecture in and of I'm probably biased in that I've only ever used monoliths for any non-trivial webdev project, be it professional or personal. Microservices seem nice in isolation if you can have one team own one or two services each, but trying to imagine developing and reliably testing more than a few concurrent web services makes me break out in a cold sweat. , the site has a great list of static site generators. I've been reaching for Go more and more often for various scripts and small programs lately, so I decided to give Hugo a try. Since Hugo is a single binary, it would also solve some of the performance kinks from the Ruby-based Jekyll.

The Hugo docs start out by listing all the CLI commands you can run to do things like install new themes or create new pages. The docs then sharply pivot to a dictionary containing the definition for every single word associated with the project. I'm sure it's a great framework for static frontends (every review I've read of it has been glowing) but it's very frustrating to have to read through dozens of pages of vaguely relevant documenation or watch third party video There's nothing I hate more than technical video tutorials. At least with docs I can Ctrl-F, skim, have multiple tabs open, etc. With videos none of this is possible except maybe playing at 1.5x speed, and that just gives me a headache. Combined with having to sit through minute-long intros, ad reads, and general clunkiness ("Woops, I misspelled something! Let me slooowly drag my mouse cursor over, click, drag, then type it out via hunt-and-peck again..."). If you're a visual learner, I don't know how you manage to get anything done this way. just to answer basic questions like, "How are pages routed?" or "What's the difference between a layout and archetype?". I think I just about got an index page up and running before just cutting my losses and giving up.

Next.js

This is where I'm at right now. Next.js is definitely a far cry from the simplicity I was originally looking for, but a number of factors influenced this decision. First, I'm already familiar with React and I'm a fan of JSX and its abilities in terms of templating. Secondly, no matter how diligently I follow security checklists for managing Internet-facing web servers it nevers fails to give me the heebie jeebies, so I was interested in using a CDN service like Netlify or Vercel which Next.js happens to mesh well with. Thirdly (and I am not in the least way ashamed of this), Next.js seems hot right now so I wanted to check out the buzz and practice some résumé-driven development.

I really like that Next.js leaves it entirely up to the developer to define where data is coming from and what it looks like, unlike Jekyll or Hugo where content is assumed to be a Markdown file from one specific location in the directory structure. Right now I just have a tiny function to fetch and sort posts by date from a directory, but if I really wanted to I could stick everything in S3 and do some crazy serverless setup (way overcomplicated, but an example of what's possible). Because it's all JavaScript I can also have arbitrary programs that run at build time and do things like build the RSS feed without any platform-specific plugins or APIs, just node scripts that have the ability to share code with the frontend.

Like I mentioned at the start of this post, I'm still not really satisfied with this setup. My more conscientous side feels guilty about using so much technology just to serve up static documents, and I don't really know if I can justify the time I've spent just to save myself some repeated keystrokes and due diligence. I suppose what I'm really after is a good templating library, a performant build system to tell me when I've broken something, and some functions that basically let me say, "Here's a directory, let me filter, sort, and iterate through all the files in any way I like". I could probably spend some time and hand-roll one of my own that's a joy to use (I'm an Emacs user, after all), but that's probably a project for another time. I doubt the world really needs yet another static site generator, anyway.