code & computationα

Adrien Lamarque

Hugo: the good, the bad and the ugly

POST — published:

There’s a lot of competition in the space of static sites generator: the idea of generating content statically is more popular than ever as people realize that the bloat and unresponsiveness of JS-heavy websites doesn’t make sense when you mostly want to display static content.

When building my own site, I ended up trying two different options: Pelican and Hugo, and ultimately chose Hugo because it offered better default themes (which, in the end I didn’t use) and promised to be fast, even with a lot of content. However, not everything is perfect in Hugo-land; and some of its limitations, which are not apparent at first, may be quite severe depending on your use case.

Let’s review what I liked with Hugo, and what I disliked.

The Good

  • Easy to install: Hugo benefits directly from being written in Go for two things. First, unlike many other languages, Windows is a first-class citizen (well, almost) platform for Go. Secondly, by default Go binaries are completely statically linked. As a consequence of these, I only have to download a single hugo.exe / hugo executable and put in the PATH of my Windows and Mac OS X machine to get a completely equivalent workflow on either machine.

    (On the other hand, a pelican setup would have involved installing inside a virtualenv, using pip… A path which is fraught with much danger of random breakage.)

  • Hugo is particularly suited for blogs, as it provides a lot of the features that you might want out-of-the-box: things like Markdown support, automatic RSS generation, and plenty of themes in the community. It is super easy to start a blog with it.

  • Fast: it’s one of the main selling points of Hugo, and even though I can’t say I have enough content on this site to know if Hugo holds its promises or not, I am very pleased with the fact that Hugo builds my site completely instantaneously, even including drafts. This is important, because Hugo has…

  • A good development server, which recompiles the site on-the-fly whenever it detects changes. That way, I don’t need a fancy Markdown editor: I can just split my screen in two, with my editor on the left and the browser on the right, and immediately see the draft I’m working on being rendering. A quick feedback loop is quintessential to being productive, and you really can’t beat instantaneous feedback.

  • Hugo is also flexible: while most generators only allow you to build glorified blogs, Hugo offers allows you to build different types of content, and to specialize on each. It also offers taxonomies, which are basically types for metadata that your content can have—like tagging and categorizing blog posts, for example. (These would be two taxonomies called tag and category, respectively, and each post would contain metadata listing the tags it has and the categories it belongs to.) It also allows building single, one-off pages (like the about page on this blog).

    Hugo relies on Go templates (with a little extra functionality), and includes a mechanism for overriding theme defaults; a theme that’s build with customization in mind will thus be very easy to customize.

The Bad

  • Documentation is large, but sometimes confusing. Some of it is out-of-date, and a lot of the information is scattered around in different pages, to the point where it’s hard to get a simple “bird’s eye view” of things.

  • Syntax-highlighting is outsourced to Pygments, which requires a functional python installation and possibly a virtualenv, which negates a little bit of the benefit of a single static executable mentioned earlier. It’s not a big problem for me as I don’t use any syntax highlighting for now, but I’d have preferred another solution. (Hugo does offer the alternative of doing client side highlighting with a JS library, but I don’t think that really makes sense when you’re trying to avoid any kind of client heavy workload…)

  • Typography: Hugo offers a few automatic typography improvements, but for anyone concerned with proper typography they’re unfortunately only a band-aid. One of my complains about it, in particular, is that they only support American-English typography. Should I want to write to include blog content in French in the future, some of these typography improvements would be ultimately wrong. (For example, French quoting rules are different from the English-speaking world.)

The Ugly

  • Markdown rendering is only possible through Blackfriday, a markdown renderer written in Go. There is no possible alternative, as Hugo calls the renderer directly from its code, and is completely dependent on it.

    Blackfriday does have plenty of features, but it cannot possibly cover all the needs that everyone might have. In particular customizing the HTML output involves either monkey patching some of the code or just forking Blackfriday completely—in either case, Hugo has to be forked as well to replace the calls to Blackfriday.

  • Feature creep is getting me a little worried. I feel that the project has been adding a ton of new small features that feel somewhat “hackish” instead of the right abstraction to build the features upon. For example, Hugo allows what’s called shortcodes which are a tag-like syntax to include custom HTML directly within the Markdown content. (This relates directly to the point about Markdown rendering above.) If such functionality is required, I think we should be able to directly extend the Markdown renderer rather than cram custom notation on top of Markdown. If the Markdown isn’t going to be standard anymore, I’d rather have at least the possibility to extend the syntax!

Hugo and I

The last two points evoked may very well be the things that make me move away from Hugo in the future, but I’ll stick to it for now. After a little customization, it offers ninety percent of what I want from a static site generator, so I can focus my energy on improving my writing in the first place. With time, maybe my biggest complains will be solved, and if not, I already have a few worthy successors in mind to look deeper into—Hakyll and Pollen, in particular.