My review of Hexo, a Node-powered static site generator
Tags: node, javascript, bash, codenewbie
Published: 2020-05-29 01:48:42

I’ve been wanting to experiment with static site generation for awhile now, and after researching a few options, I decided to go with the [Hexo framework](https://hexo.io/) — mainly because of the number and quality of themes available for it. Hexo is a free to use Node-powered static site generator that was originally launched by Tommy Chen in 2012, and it seems to still be going strong 8 years later.

I’ve been using Hexo on this site for around three months now, and I’ve published five or six posts in that period, so I’ve had enough time to play around with the framework in depth. I’m a designer whose knowledge of web development is spotty at best — indeed, the gaps are probably wider than the filled areas. I don’t consider myself a developer (yet), but this project was a testament to the fact that I can figure things out with enough Googling and intuition. Turns out that I’d need both of those things pretty much immediately upon trying to install Hexo, but that wasn’t necessarily Hexo’s fault.

This walkthrough is meant to summarize the steps I took to get Hexo up and running, as well as highlight some of the errors I encountered, along with how I went about solving them. It’s written for beginner developers or non-developers who may not understand what to do when troubleshooting their own instances of Hexo.

![Hexo homepage](https://dev-to-uploads.s3.amazonaws.com/i/jbrdbst71sjixn7ae6pe.png)

## Make sure you have the right version of Node.js installed in the right directory

Given the fact that Hexo is powered by Node, it stands to reason that you would want to make sure you have Node installed on your machine (I’m using a Mac). If you’re like me, you might have installed Node awhile ago without having to touch it much, and you may not initially realize that you can have multiple versions of Node installed in different directories (especially if [Homebrew](https://twitter.com/bitandbang/status/1257361802125611008), [Yarn](https://github.com/hexojs/hexo/issues/3348), or other package control comes into play).

That’s essentially what I ran into when I ran `npm install -g hexo-cli` only to get my first of many error messages:

```
/usr/lib/node_modules/hexo-cli/node_modules/chokidar/index.js:150 async remove(item) { ^^^^^^

SyntaxError: Unexpected identifier at createScript (vm.js:56:10) at Object.runInThisContext (vm.js:97:10) at Module._compile (module.js:549:28) at Object.Module._extensions..js (module.js:586:10) at Module.load (module.js:494:32) at tryModuleLoad (module.js:453:12) at Function.Module._load (module.js:445:3) at Module.require (module.js:504:17) at require (internal/module.js:20:19) at Object.<anonymous> (/usr/lib/node_modules/hexo-cli/node_modules/hexo-fs/lib/fs.js:6:18) at Module._compile (module.js:577:32) at Object.Module._extensions..js (module.js:586:10) at Module.load (module.js:494:32) at tryModuleLoad (module.js:453:12) at Function.Module._load (module.js:445:3) at Module.require (module.js:504:17)
```

Internet research led me to a few tangentially related StackOverflow questions in English, as well as a bunch of directly-related questions in Chinese. Thankfully, Google Translate helped me see that [a few](https://gis90.github.io/articles/10512/) different [people](https://issuehunt.io/r/hexojs/hexo/issues/3781) had the same issue as me, and it was due to a Node version that was out of date, and thus incompatible with Hexo.

I proceeded to update Node, but the old version was still being referenced in my project directory for some reason. I then tried reinstalling Node with Homebrew, but that didn’t work either, so I once again turned to Google. It turns out [someone else](https://stackoverflow.com/questions/43218630/node-using-wrong-version-after-brew-install) had similar problems with Homebrew + Node in certain situations, so I tried what they did and uninstalled Node altogether to get a fresh start.

Based on the advice from that StackOverflow thread, I used NVM (Node Version Manager) to install Node this time. This is where the next two road blocks came up – first I had to fix two bash issues to get NVM installed at all. To be fair, this was more a me problem than a Hexo problem.

Terminal had been prompting me to update from bash to zsh because “the default interactive shell is now zsh” (I don’t actually have any idea what bash or zsh are), and I mistakenly made that update while I was in the midst of my Hexo set-up. This of course caused even more issues to crop up. It didn’t take an internet search to figure out that changing to zsh from bash caused my new road blocks. Instead of trying to make zsh work, I decided to just revert back to bash.

After solving that problem, and scrambling to solve a secondary bash profile issue, I was finally able to install NVM and then use it to re-install Node, which thankfully solved the weird version inconsistencies. Finally, finally, `npm install -g hexo-cli` worked the way it was supposed to!

## Beware special characters when using YAML & markdown to write posts

Hexo’s blog post format combines a YAML front-matter area containing post meta-data, and a markdown section below it within which to write the body of the post. Coming into this project, I had lots of experience working with markdown, and had previously worked with YAML front matter on Dev.to’s posting platform. Thankfully, it was pretty straightforward to apply that knowledge in this capacity, with one glaring exception – apostrophes a.k.a. single quotes.

It’s an easy thing to get tripped up by if you’re not paying attention, and honestly I should have known better given the havoc special typographic characters are known to wreak in other languages. The need to escape apostrophes in YAML didn’t occur to me until I’d just about started banging my head against the desk trying to figure out why I kept getting errors similar to these when I tried to use `hexo generate` to generate a static site from my first blog post:

```
YAMLException: can not read a block mapping entry; a multiline key may not be an implicit key
```

```
"hexo" FATAL can not read a block mapping entry; a multiline key may not be an implicit key at line 9, column 9:
```

Although Hexo’s [docs](https://hexo.io/docs/troubleshooting#YAML-Parsing-Error) mention troubleshooting YAML parsing errors, they cover the use of soft tabs and adding a space after colons, but they don’t really touch upon special characters as a possible source of bugs too. And the [YAML spec](https://yaml.org/spec/1.2/spec.html) that Hexo’s docs link to, while obviously comprehensive, is overwhelming when trying to debug an issue like this one.

Thanks to even more helpful [internet research](https://chrischen0405.github.io/2018/11/21/post20181121-2/), it turns out I’d been using an unescaped single quote in one of my post titles. Before I realized the root of my problem was single quotes, I’d been looking at everything from hidden non-English characters, to trailing spaces as possible sources of my road blocks.

Even better, after all that frustration, all it took was adding one more single quote next to the original single quote to fix the problem. It’s a lesson I learned at least once more when I carelessly added an unescaped single quote to my blog description in the `_config.yml file`, which is where most if not all of the global site settings are stored.

I found [this primer](https://docs.octoprint.org/en/master/configuration/yaml.html) on YAML by OctoPrint to be helpful in summarizing some of the common pitfall areas that people encounter in these scenarios – because it turns out there are a variety of ways [people](https://github.com/hexojs/hexo-migrator-rss/issues/10) can [get](https://github.com/hexojs/hexo/issues/2386) tripped [up](https://blog.csdn.net/zyupupup/article/details/85098366) by syntax despite YAML’s seeming simplicity.

## Hexo themes extend customizability beyond just styling

The main selling point that convinced me to go with Hexo compared to other static site generators was the number of promising themes its robust community has provided over the years. I chose Pieter Robberechts’s [Cactus theme](https://github.com/probberechts/hexo-theme-cactus) because it aligns with the vision I have for this site, and because it has great documentation. Something I was also pleasantly surprised by was the way themes like Cactus can extend Hexo’s features without the need to install individual plugins.

![Cactus theme homepage](https://dev-to-uploads.s3.amazonaws.com/i/noh5e6pzdpt3bouddc1p.png)

With Cactus, I’m able to easily switch between light and dark color scheme variations, change my code highlighting scheme, add a projects list to my site, and a lot more. Some of these are features that I probably could have added to Hexo via individual plugins, but it’s so much nicer to have them all in one theme/place with clear documentation and thoughtful integration.

One point of frustration I *have* experienced with Cactus, and which I would have experienced with *any* theme I’d chosen to go with, is going beyond its built-in customizability. Full disclosure: This is because of my lack of domain knowledge, and not a fault of the theme nor the framework.

A case in point here is table styling. I decided I wanted to change the way my tables are styled in Cactus theme, but am not super knowledgeable on compiling CSS and basically just hacked together a plain CSS solution. I know it was the wrong way to have done it, but considering how much time I’ve spent troubleshooting just to get to this point with Hexo, I decided the trade-off of time spent figuring it out wouldn’t have been worth it to me at that moment in time. I know I may come to regret that decision later on, but I’ll cross that bridge when I get to it.

## Conclusion: Hexo’s worth it so far

Despite the copious amount of roadblocks I had to get through first, three months after first starting to use it I’d say I’m happy with Hexo overall. I really like the workflow I’ve developed with it, even though I’m still manually deploying the site at the end of it because I couldn’t get deployment to work and was sick of debugging one of three personal sites I currently maintain. The convenience of being able to continue writing my posts in markdown while being able to produce static, interconnected HTML pages of those posts with a single `hexo generate` command has made a lot of the headaches worth it.

Also, I’d like to note that I’ve had mixed results with plugins so far, but I’ll have to explore their capabilities and results a little more before I give any definitive opinion on them. The one bad plugin experience I’ve had so far was with the `hexo-image-caption` plugin by Wayou – I just wasn’t able to get it to work. A good plugin experience I had was with the Google Analytics add-on to Cactus theme.

I’d hesitate to recommend Hexo to everyone, but I will say that it might be a good fit for you if you’re looking for a markdown-based, Node-powered static site generator for a blog. If your development knowledge is non-existent or entry-level, then it might also help if you’re a very curious and patient person who’s convinced every problem is a knot that can be unravelled. If you have any questions or feedback about my experiences with Hexo so far or about your own experiences with it, let me know!

---

I originally published this post on May 2, 2020 on [practicing.design](http://practicing.design/2020/05/02/my-review-of-hexo-a-node-powered-static-site-generator/)