Jekyll vs Hugo vs Gatsby vs Next vs Zola vs Eleventy
This blog is now a few years old, so I felt it was time to do some housekeeping. I cleaned up old posts, got a better domain, and experimented with static site generators. That last part is especially interesting, and it's what I want to write about today. I tried out Jekyll, Hugo, Gatsby, Next, Zola, and Eleventy. These are my thoughts on each.
Jekyll
I've used Jekyll on this blog for the past four years. As the "OG" static site generator, it has an easy learning curve and a moderately active community. It's similar to an Apple product: a little opinionated, but if you follow its guidelines, it just works. It's also pretty easy to customize if you want to make your own theme.
One of Jekyll's pain points is its build speed. (Jekyll 4 makes some speed improvements, and you can also enable incremental builds with jekyll serve --i
, but you'll still need to do full builds to pick up new posts. Relative to other static site generators, it's one of the less convenient options.) To use it, you'll also need to set up a Ruby development environment, and extending it with your own shortcodes requires some Ruby knowledge.
Paul Stamatiou (@stammy) and I share the same feelings about Jekyll:
If I was building my site today, I would be considering a faster, newer static site generator like Hugo for a few reasons. First off, Jekyll is slow, especially when you have over 1,000 posts like I do. Depending on the machine I use to generate the site, it can take anywhere from 7 seconds to 90 seconds to compile. Hugo claims this can be done 100x faster.
Second, Jekyll relying on a Ruby environment is a hassle. Getting a new environment setup on a new machine is always a pain, with some gem always being reluctant to install and leading to Googling about 5 different issues before it's resolved. – Paul Stamatiou, About this website
All-in-all, Jekyll is a strong choice for small blogs, but there are some more modern options if you're looking at making blogging a long-term thing.
Hugo
The first time I used Hugo, it generated my blog so fast that I thought it was broken. That's its main benefit: speed. It'll generate most personal blogs in milliseconds, taking around ~2ms per post. It also comes with hot reloading, sitemaps, and RSS feeds out of the box. This is great if you want to take blogging more seriously: the speed and hot reloading makes it painless to preview content as you write, and sitemaps are great for SEO.
The other thing I absolutely love about Hugo is that it's a single binary, which means that it's easy to install. You don't need to rely on a package manager or set up a development environment. On Mac, you can run brew install hugo
to download it, and you're ready to go. This is a huge plus if you're planning on working on a team: your teammates won't need to manage lockfiles or worry about their development environment. They can just... write.
Flavio Copes has a great quote about Hugo in his post "The pros of using a boring stack":
Definitely don’t work on your blog infrastructure if you want to do any serious blogging. [...] I use Hugo, a static site generator. Hugo is the best one for me as it’s focused on blogging and markdown. It is boring. Its templating language is boring. It’s so boring that when I have to tweak something I fall asleep. I love it. — Flavio Copes
That being said, Hugo has some downsides. It uses Go's html/template
and text/template
as its basis for templating, which isn't as expressive as some of the other templating languages available. For most people, this means that Hugo will have a higher learning curve than other options. And this is prevalent in a thread on Hacker News, where people are saying:
"If anyone is considering using Hugo, please account the tens of hours you will spend debugging its weirdness and magic." — shubhamjain
"Hugo has gotten very confusing as it has become more powerful. They are moving so fast and people are doing crazy stuff with it now! As the maintainer of a simple Hugo theme and a few simple blogs I can hardly keep up." — aorth
"It IS a pain to make anything that deviates from the golden path that's shown in the documentation." — gima
Hugo is a great choice if you're comfortable with Go and you want to make a relatively simple blog. If you want to extend it, though, you'll need to take the time to learn its magic. There are still other options with easier learning curves.
Gatsby
Gatsby is the hottest static site generator at the moment. I've interacted with the team on GitHub, and they've always been friendly and responsive to issues. At the time of writing, they've raised $48.6 million in funding.
Gatsby has the best documentation out of every static site generator I've used. (I first tried Gatsby years ago when their documentation was much worse. If you were turned off by them in the past, they've made a lot of improvements in the last few months.) I also love that they've put care into the "little things", like their CLI and the design of their docs, which are often ignored by other generators.
Gatsby also allows you to write MDX: JSX-infused Markdown. Meaning, you can embed React components in your Markdown:
---
title: My post
---
import Something from '../path/to/Something'
Lorem ipsum dolor sit amet.
<Something foo="bar" />
There are a few downsides to using Gatsby for a personal blog:
- It requires you to use GraphQL, which is overkill for most use cases. Most static site generators let you add a variable to your frontmatter and immediately reference it in your templates, but not Gatsby: you'll need to glue them together with GraphQL queries.
- You need to ship React alongside the rest of your site. This makes your initial page load heavier. Subsequent loads are smaller, but the average reader probably doesn't visit enough pages to make this worthwhile. For most personal blogs, you end up transferring much more over the wire with Gatsby than you would otherwise. If you have a lot of traffic, this can also increase your costs.
- Starting a local development server is slow. Building is slow. And long build times can also lead to higher costs. (I believe that the Gatsby team is working on incremental builds through Gatsby Cloud. If you use Gatsby, it would be worth taking a look at their hosting service.)
- Every time I use Gatsby, I still encounter bugs at a higher rate than any other generator. I find myself running
gatsby clean
to dump the cache in every other session. On one of my (fairly small) sites, the dev server would freeze until I resized my terminal. You also need to watch for rehydration issues. - You'll need to handle everything via JavaScript. If you want to install analytics or use Google/Typekit fonts, you can't just paste in the embed code; you'll need to install a plugin or use React Helmet for that. If you want to run JavaScript in your footer, you'll need to work within the boundaries of React. Sometimes I like the bare metal that vanilla HTML provides.
Those disadvantages drive me away from using Gatsby for a simple blog. I think it's a great choice for marketing sites and storefronts, but I don't think many blogs actually require its functionality.
Next.js
Next.js is another React-based framework that can support static sites. Its "getting started" tutorial is stellar, and the team behind it has some incredibly talented developers. For a blog, Next.js requires more assembly than something like Gatsby, but it doesn't force you into using GraphQL. It automatically imports React so you can write components without any boilerplate:
const Example = () => <div>...</div>
export default Example
Like Gatsby, it's also possible to support MDX without too much configuration. That means that you can use JSX inside your Markdown files, same as earlier:
---
title: My post
---
import Something from '../path/to/Something'
Lorem ipsum dolor sit amet.
<Something foo="bar" />
However, unlike Gatsby and the other entries on this list, Next.js doesn't provide blogging-specific features. For instance, if you want to generate a sitemap, you'll need to write code for that yourself, which means you'll need a way to group and categorize your posts. You'll also need to write components for rendering Markdown, and you'll need to determine how you want to pre-render files:
Next.js has two forms of pre-rendering: Static Generation and Server-side Rendering. The difference is in when it generates the HTML for a page. – NextJS Docs
In addition to this, you'll still need to send React to every visitor.
Basically, Next.js seems awesome for building apps, but I don't know if I'd choose it for a serious blog. There's just too much configuration that you can get out of the box with other frameworks. (And I know there are Next.js starter blogs, but they're usually lacking some important feature: a sitemap, categories, and so on.)
Zola
Zola is one of the lesser-known static site generators on this list, but I really like it. It's basically Hugo, but written in Rust, and it uses a more sensible templating language:
- Its build speed closely matches Hugo.
- It uses a single binary, so it's very easy to set up. On Mac, you can just run
brew install zola
. This also makes it easier if you're working with a team. - It will automatically generate sitemaps for you, which is good for SEO.
- It uses a sane templating language called Tera which is very similar to Liquid. This makes it very easy to customize the design of your site.
- It can handle things like syntax highlighting, tables of contents, automatic header anchors, Sass compilation, and hot reloading out of the box.
- It doesn't have a lot of frills, so you can just focus on blogging.
- I've found its documentation easy to navigate, and it has a nice CLI.
One drawback is that it forces you to use TOML instead of YAML. This sounds tiny, but it can be a huge pain to migrate if you have an existing blog where every post has many lines of frontmatter already set in YAML. So instead of using ---
and :
, you'd need to use +++
and =
:
---
title: Most site generators use YAML
foo: bar
qux: quux
---
Your content goes here...
+++
title = "But Zola only lets you use TOML"
foo = "bar"
qux = "quux"
+++
Your content goes here...
I really like Zola, but it's the only site generator that doesn't offer a YAML option, and this makes migrating existing sites more difficult. Other than that, it's pretty easy to work with, and the documentation is good.
Eleventy
Eleventy is written in JavaScript, but it doesn't add any client-side JS and it doesn't add a framework to your site. This means that you can ship plain HTML and CSS with no bloat. (Eleventy's docs explain that they're opting out of the framework rat race: betting on JavaScript without locking themselves into a specific framework.) It comes with a ton of benefits:
-
It's flexible on your directory structure, so you can customize your workflow to suit your needs. For instance, I have
articles
,code
,books
, anddrafts
on my site, and I've sorted them into folders like this:posts/ articles/ article-post.md code/ code-post.md books/ book-post.md drafts/ draft-post.md
Then, you can assign frontmatter properties, such as categories and tags and permalink structures depending on what directory a file is in. This makes it very easy to blog with.
-
You can add your own shortcodes with JavaScript:
eleventy.addLiquidShortcode("exclaim", (phrase) => ` <b>${phrase}!</b> `);
-
It works with several template languages, and you can use them all interchangably in the same project: HTML, Markdown, JavaScript, Liquid, Nunjucks, Handlebars, Mustache, EJS, Haml, Pug, and template literals.
-
It builds much faster than Jekyll and Gatsby, and it also supports hot reloading, so you can live-preview your blog as you write.
Eleventy has a few small downsides: its documentation is still a bit disorganized, and I find myself searching for blog posts to cover the gaps in my knowledge. And also, parts of your site are still low-level; for instance, if you want all of your CSS to be bundled into one file, you'll need to create a file and include
the CSS yourself. Same for the sitemap, although I have a post on that now.
I don't love the reliance on npm, but I understand why it's necessary. (And it's probably a huge pro for a lot of developers!) Still, my ideal generator would be a single binary.
Conclusion
Go with Jekyll if you already use Ruby and plan on having a small blog where you don't publish often. Vitalik Buterin or Tom Preston-Werner come to mind on the ideal size for a Jekyll blog. I have an article on setting one up here.
Go with Hugo if you're planning on having thousands (or tens of thousands) of posts and don't mind its templating language and learning curve. Think Flavio Copes who publishes a new snippet for developers every day. It's also great for teams because it's easy to install and maintain.
Go with Gatsby if you want to write interactive blog posts and use MDX, like on Josh Comeau's blog... as long as you don't mind its build times and using GraphQL to glue it all together.
Go with Next.js if you want the interactivity that comes with a React-based website but don't want to mess with GraphQL. Paco Coursey's site is a nice example; you can press ⌘
+ K
to open the menu and browse the contents.
Go with Zola if you're planning on having thousands (or tens of thousands) of posts and don't mind using TOML. Since it comes in a single binary, it's also great for teams.
Go with Eleventy if you want a fast-building blog that's easy to theme, extend, and customize. Eleventy is the easiest to learn on this list, and it would be my recommendation for most people these days, as long as they don't mind using a little bit of JavaScript. The various templating languages are also a plus. I have a walkthrough on how to set up an Eleventy blog here, and I highly recommend you check it out!
Eleventy is my new favorite static site generator. It hits that sweet spot of being minimal, yet flexible. And as a result of this experiment, this blog is now built with Eleventy.