Michael Blum

Developer from Chicago

Migrating From Jekyll To Hugo

Migrating from Jekyll

Why go to the trouble? While Jekyll has been good to me and shown me the light of static blogging, Jekyll’s unabashed Ruby / Ruby on Rails underpinnings lead to some interesting problems:

1. Ruby version / Ruby env problems

Recently update your operating system? Via brew pr another tool? Chances are your Ruby environment will complain. Since I’m not a ruby person by trade, I haven’t devoted the time to running ruby well.

This is why previously this blog used a Dockerfile to containerize the Ruby version and build dependencies:

FROM ruby:2.3

RUN apt-get update >/dev/null \
    && apt-get install -y locales libmagic-dev >/dev/null \
    && apt-get install -y libxml2 libxml2-dev libxslt1-dev >/dev/null

RUN mkdir -p /opt/project
ADD . /opt/project/
WORKDIR /opt/project

RUN bundle install --jobs $(nproc) --path=/cache/bundler

RUN bundle exec htmlproofer --disable-external --alt-ignore /amazon-adsystem/ _site

2. Very slow

This is by no means a fault of Ruby as a language but rests at the feet of the gems written in Ruby. Prime suspect amoung them is the venerable nokogiri tasked with linting and validating HTML. As of this writing the longest part of running bundle install` is installing nokogiri.

3. Tight coupling of theme and content

While many Jekyll themes exist as Ruby gems, others are HTML and CSS that are passed into the asset pipeline. When I wanted to change a theme - this would involve changes to the asset pipeline.

Enter Hugo

Built with Google’s Golang, Hugo is next-generation static blogging. While Jekyll was the trailblazer of static blogging, Hugo has built on those concepts:

1. No environment dependencies

One of the pillars of Golang, and by proxy Hugo, is the ability for any project to compile down to a single binary.

2. Greater flexibility

While Jekyll tries to make everything a Post, Hugo expects you to have a template for each type of content you’re creating. This explicit templatingf makes for a very clear schema and allows for modular design of each type of content.

3. Seperation of form and function

Prehaps Hugo’s greatest feature is the extension of flexible content into flexible themes as well. Each theme in Hugo exists as a seperate git repository. Next post will detail how this works.

Installing it on Mac is as simple as brew install hugo

Migrating this blog was as easy as checking out the git repository, creating a feature branch in a seperate directory and running hugo import jekyll.


As yet another Jekyll -> Hugo migration post - here are the compilation benchmarks:

Jekyll (deploy.sh) Hugo (hugo benchmark)
0.44s user Average time per operation: 81ms
0.71s system Average memory allocated per operation: 12690kB
1:46.50 total Average allocations per operation: 179047

Linting aside on the Jekyll side, not haing to install a bunch of dependencies makes for orders of magnitude faster builds.

Next up, I’ll show you how this theme was ported to Hugo.