Migrating from Jekyll+Github Pages to Hugo+Netlify

During the last 18 months, working on my Web site became a daunting task—be that for developing, redesigning it, writing a blog post, or making updates to my speaking and workshop pages. My then static site generator, Jekyll, is why. And a change has long been overdue...

Jekyll became unbearably slow at compiling my Web site after every change I made. Until, at one point, waiting for the site to compile became a torturous, life-sucking process that I wanted to avoid at all costs.

This may sound exaggerated, but I promise you it’s not. Jekyll became way, way too slow. “Too slow” is actually an understatement. Recently, every time I changed a CSS property or made any change in the HTML I had to wait up to five minutes for that change to be picked up and compiled by Jekyll. I am, once more, not exaggerating. Jekyll used to literally just… freeze. I’d have to ctrl+C my way out of the freeze and then run it again for it to pick up the changes and finally compile. And if I made many changes in a row, my Macbook would heat up so much and the fan would go so crazy that it sounded like an airplane about to take off.

My site is relatively small, I’d say. I have less than 100 blog posts. Less than 60 at the time of writing of this article, actually. And only a few static pages. I don’t use heavy JavaScript. In fact, I barely need to use any JavaScript. And yet, Jekyll still choked every time it had to compile it.

Yes, I did use Jekyll flags such as --incremental and every single other flag and setting that I found or that someone recommended to speed up the compiling process. But no, it did not help.

I can’t even emphasize how bad it got during the last year. I would literally feel the stress hormones increase in my blood stream every time I so much as thought about making a change to my Web site. I knew I would be about to give myself one hell of a bad time doing so.

But I knew that this couldn’t go on forever. I knew I’d have to ditch Jekyll and migrate to a new generator at some point. I just never found the time to do so. Actually, to be more honest here, I never made the time for it because every time I had time off a project I wanted to make the most out of that time by staying away from my computer. My site was just not a priority, especially since I’d been very much still undecided about what to use as an alternative. So I kept stalling.

But recently, knowing I had a couple of weeks off to do practically anything, and since I’ve been having a lot of ideas for my blog that started piling up and that I really want to get out there, such as a setting up a newsletter, tweaking the design, improving the code (which is still WIP), adding a new type of content section (coming soon) and a few more ideas, I finally managed to put my head into it and do it, because I want to get my ideas out, and write a few blog posts. But I needed to start enjoying working on my Web site again, first. So I finally thought to myself: “That’s it. I’m just gonna have to put my head down for a few days this week and dedicate my time to moving to the new static generator”. I knew this was a necessary and extremely useful time investment that I just had to finally make. I put my mind to it, and just did it. (This is the most effective way to be productive, really: Just do it.)

Choosing a static site generator

As I mentioned earlier, one of the reasons I didn’t make the switch earlier to another generator was because I didn’t know which one I wanted to use. Several Twitter friends suggested a few of the many available options. But I never felt comfortable with any of them. You see, everyone has some way that their brains work, and some way they like to organize their files, directories, and work, that works for them. None of the static generators I saw gave me everything I wanted and needed for my site. Until someone once suggested having a look at Hugo.

I took a few minutes to read the docs, just to get an idea of what to expect and what Hugo had to offer—to get a first impression of it, so to speak. After reading a little into the content structure and organization section and learning how Hugo offers the ability to create many different content categories and sections, plus all the general flexibility it provides, I thought that this was the static site generator I’d always wanted and needed. The organization and structure looked exactly like what I had imagined my own site to have.

But what made me settle for Hugo out of all other options was seeing how incredibly fast it is compared to Jekyll. Not only has every single blog post I read online made a comparison and proved this, but I also got to experience this speed first hand while working on the Smashing Magazine redesign.

The new Smashing Magazine (currently at next.smashingmagazine.com) uses Hugo as a static site generator. The setup that I got to use while building the front-end of the magazine was so blazingly fast that I had absolutely no doubt that the results I was reading about were true. And since my site is much smaller than Smashing Magazine, I knew I had nothing more to worry about. I mean, if Smashing Magazine can be compiled so ridiculously fast, how could my blog not be?

Please note that this is in no way meant to be a comprehensive guide to Hugo. There are still some bits and pieces that I am figuring out myself, so I'm in no position to write a comprehensive guide yet. You will find that you will also need to read through the Hugo docs for more details on the topics I’m going to be talking about. Think of this post as a helper that can help guide you where to start (and sometimes what to do) for certain particular Hugo topics. And finally, this is not a comparison post between Hugo and Jekyll. This is more of a Hugo starter tips kind of article. If you’re considering Hugo as your new static site generator, I hope you find some useful tidbits in here to help you get it up and running.

Setting Hugo up

Setting up Hugo isn’t complicated. The docs include two guides: one for installing Hugo on a Mac, and one for installing it on Windows. From here on forwards I’ll be referring to a Mac setup since a Mac is my main work machine.

I used brew to install Hugo:

$ brew install hugo

I followed the instructions in the installation page and updated brew and ran a few other commands to ensure everything was installed and working as expected. That’s all you need to get Hugo to work and run on your machine. It can’t get any simpler than that. With Jekyll, installation didn’t go as smoothly as I remember spending quite a lot of time to get it set up and running back then.


I tend to be a lazy developer sometimes. But that can be good because it pushes me to find the fastest and simplest way to accomplish a task. So the first thing I wanted to do in making the switch to Hugo was a way to automatically migrate all my blog posts without me having to go over each and every one of them to change the front matter in each one. (Seriously, I would have aborted this whole operation if I had to do that. 😅)

Fortunately, as of version 0.15, Hugo provides a one-liner to migrate from Jekyll. You type the following line into the terminal—replacing jekyll_root_path and target_path with the paths to your current Jekyll directory and the directory you want to set up your new site in, and Hugo will import your current Jekyll site’s files into a new Hugo site directory for you:

hugo import jekyll jekyll_root_path target_path

If you’re not importing a Jekyll site, you may want to check the corresponding docs out, detailing what you need to know about folder structure in Hugo, such as where static assets go, where content and layout templates go, and more.

The next step is to convert your Jekyll templates into Hugo templates, and this is where the bulk of the work is, and where I ended up bumping my head into the walls quite a few times. (But believe me, the end result I have now is very much worth it. Plus, I’ve learned a lot. I’ll be sharing some of what I learned in the next section.)

You may be a different kind of lazy developer. For example, you may prefer to start with a boilerplate that provides you with the setup you need, and that is ready for you to start adding content to right away, especially if you're starting a blog from scratch. In that case, I highly recommend Netlify’s Victor Hugo boilerplate, which comes equipped with everything you need to even get Webpack and Gulp up and running in your site’s Workflow as well. The structure the boilerplate provides is slightly different from what I have below, but not too much.

Diving into Hugo: Technical details

Let me start by saying this: at some point during the migration, I was just tweaking stuff, changing values, names, file names, structure, etc. in the hopes of something magically working and when it does I would go like: “I have no idea how or why this worked.” And as someone else mentioned on Twitter, apparently I’m not the only one who’s had such moments with Hugo. So I’m hoping this (fairly long) post will help some of you thinking about making the switch to Hugo, hopefully saving you some headaches along the way.

Disclaimer: There’s a lot about Hugo that I still don’t know how to do and find myself Googling sometimes. But I’ve got all the basics and everything I need for now all up and running, and yes, I do know how and why everything I have working now is working the way it is. So, let me share some of that stuff with you. I’ll also share some of the extremely useful articles I found that helped me as well. So think of this article as an idea dump, and a set of reminders for my future self to get back to if I ever get confused again about the basics.

Please note that not you may end up not using the same process or directory structure I am using. In fact, I am sure that you won’t, unless you have the exact same content types as I do—which is highly unlikely. Also note that yo may find a better way of doing some of the things I am doing now, which is also good. And if you’re already a Hugo pro and find that some things could be done in a better way, please do feel free to share your ways for the rest of us to learn from.

Hugo Folder Structure

My site’s local directory structure currently looks like this:

Hugo Folder Structure

The folders you see in the image above, apart from node_modules, are the ones that Hugo generates for you when you import your site from Jekyll, and these are also the ones you would normally create and set up for a Hugo site. The files at the bottom are the files needed or used by Github and Gulp. The only file that is also used by Hugo is the config.toml file.

config.toml contains the site’s configuration v