Thumbnail image

Migration from plain HTML to Hugo

Table of contents

Friendship ended with plain HTML / Now Hugo + Markdown is my best friend.

The Hugo project logo © Steve Francia 2013-2025

I’ve until now mainly used plain HTML to create my site. It was however becoming increasingly difficult to maintain as I had to create the structure by hand and add links for every new article.
I’ve since them transitioned to the Hugo Static Site Generator (SSG) after checking out the TWIG blog and wanting to have a blog with short iteration times.

This has allowed me to change from a painful process to something similar to word processing and lowers the production time from around 1 week (writing, importing external content, styling,…) to a couple of days.
In this blogpost, I am going to explain what Hugo is, what jumps and hoops I’ve had to go through to migrate my site, what was easy and what wasn’t.

What is a SSG?

Per the Awesome Static Web Site Generators List:

A static web site generator is an application that takes plain text files and compiles them to HTML files.

In a nutshell an SSG has to parse static textfiles (mostly) written in human readable text and turn it into hostable HTML. Static textfiles here refer to *.txt, *.md, *.rst, and others.

The main advantage is to allow website creation to be easier and faster, while also allowing the user to use custom HTML components if he wants to. To do this, SSG apply the Don’t Repeat Yourself (DRY) method and allow you to create site as a bunch of modules that you can reuse and import instead rewriting everything each time.

This is very useful for blogs, complex websites like digital libraries, etc.. that require a lot of duplicated code.

What is Hugo?

Hugo is a Open-Source SSG using the Go language originally created by Steve Francia (aka @spf13) and maintained as of today by Bjørn Erik Pedersen (aka @bep) and a bunch of other contributors.
The main advertised features are speed and flexibility.

Hugo site VS HTML site

The Good

  • Hugo allowed me to switch from writing and structuring HTML to simply posting Markdown. This makes Links, Images, Bold and italic text a lot more easier to integrate to the site.
    Previously, I spent a lot of time copying and pasting the structure between new articles (around 30% of the time it took to write the article was styling, setting up the <div></div>’s, …).

  • Hugo is a speedy SSG, which means sites can be built and deployed faster than raw HTML.
    Based on tests on my own site (Hugo’s internal metrics tool + Gitlab CI time), Hugo is around 1,2 times faster (~ 150%):

    Metric Time

    Template Metrics:

    cumulative durationaverage durationmaximum durationcache potentialpercent cachedcached counttotal counttemplate
    1.746423945s97.023552ms1.515849538s630018partials/head.html
    1.576550155s315.310031ms1.51682447s0005_default/single.html
    1.485952362s1.485952362s1.485952362s0001shortcodes/gallery.html
    142.984015ms14.298401ms35.934322ms00010_default/list.html
    59.703933ms59.703933ms59.703933ms0001index.html
    41.047576ms41.047576ms41.047576ms0001404.html
    35.889756ms1.993875ms6.276833ms970018partials/sidebar.html
    28.756096ms798.78µs6.019722ms980036partials/footer.html
    17.295303ms960.85µs6.217508ms660018partials/schema.html
    7.107267ms197.424µs3.859493ms1000036partials/medium-zoom.html
    6.103892ms169.552µs1.084886ms1000036partials/_funcs/get-page-images.html
    4.693051ms260.725µs1.106651ms970018partials/navbar.html
    3.942286ms1.314095ms2.64515ms0003_default/_markup/render-image.html
    3.122758ms260.229µs503.954µs00012_default/rss.xml
    2.426019ms2.426019ms2.426019ms0001portfolio/list.html
    1.29394ms35.942µs362.525µs1000036partials/math.html
    1.135572ms1.135572ms1.135572ms0001_internal/_default/sitemap.xml
    215.167µs43.033µs161.292µs100005partials/expirationnote.html
    205.362µs102.681µs155.551µs100002partials/taxonomy/tags.html
    133.736µs66.868µs94.302µs100002partials/taxonomy/template.html
    90.642µs90.642µs90.642µs0001_internal/shortcodes/ref.html
    80.36µs80.36µs80.36µs0001_internal/alias.html
    57.04µs57.04µs57.04µs100001partials/toc.html
    54.726µs54.726µs54.726µs0001_internal/_default/robots.txt
    15.583µs15.583µs15.583µs0001/scss/anatole.scss

    As for the CI Time, here it is:

    ToolNbr of pagesTime to deploy
    Hugo825 sec
    Raw HTML330 sec

    Keep in mind that Hugo has to transcode the Markdown files to HTML and bundle the assets (images, JS, etc.. ) as opposed to just existing for the HTML. So yeah it’s fast.

  • The Theme system allowed me to have a base that fits my style without starting from scratch. (Thanks Alex for the Anatole Theme). And even if something in the theme isn’t to my liking, I can edit the CSS or set custom fonts.

The “Meh”

  • Using custom components requires you to learn how to create shortcodes and partials. This requires a bit of knowledge of how Hugo works but after your first use, it’s relatively easy.
    Example for me is a custom shortcode integrating KiCanvas to embed/display KiCad files for a future project 😉.

The Bad/Difficult

  • There are some nasty bugs like Upper case letters in path causing match to fail that aren’t obvious at first. This one is sadly due to the way case-sensitive OS (like Linux) and case-insensitive OS (e.g., Windows) implement their directory API. But yeah, when you wonder why your 9999+ files aren’t built by Hugo, you start to question your life choices.

Conclusion

Even with it’s few faults, I really appreciate Hugo, as it only takes a few minutes to create a blog post instead of the days for HTML. I can concentrate on more demanding project since I know that sharing my findings will (mostly) be a turn-key solution

This also enables me to contribute to the blog despite my busy student schedule. And for that I like it!