Wednesday, December 2, 2015

Hexo, a Node.js Blog Platform

It's been five years since I wrote my first blog post, a look at XSLT that still gets pretty good traffic. I chose Blogger because it was free and easy, and the fact Google owned it gave me some confidence it would stick around.  But it's been feeling like less and less of a good fit recently.
My bread and butter as a blogger is the technical walk through, which means code,  which means angle brackets, which means using their WYSWIG editor (which does weird things to styles over the course of a post) or editing HTML directly, where you have to replace each and every angle bracket with a < and >, which is a true pain, and which I don't always remember to do.  I also really do not like the lack of versionning.  I use git commits very very regularly when I code (like hitting Save when writing a Word document), and have become accustomed to the idea I can always go back to an earlier state. The thought I might accidentally delete a paragraph from a post have to go to the Wayback machine to find it was not a comfortable feeling.

The rise of Github and Github pages, and a whole ecosystem of static site generators built around them offered the promise of easier way. I especially liked the idea of being able to author in Markdown, where code is indicated by tabbing four spaces (which MarkDown Pad can do with a single tab stroke). I was planning to look at Jekyll, but came upon a post by Kam Figy recommending Hexo. Since it is built on Node.js, there's a lot less of the "we're not sure this is going to work on Windows" about it then you will run into with a Ruby based platform, and JavaScript is a language I kind of know, unlike Ruby, which I kind of don't.

The more I've dug into Hexo, the more impressed I've been. Assuming you have node installed on your computer, set up was something you could do in seconds. The following set of commands, taken form the project home page, got me up and running locally:
  • npm install hexo-cli -g
  • hexo init blog
  • cd blog
  • npm install
  • hexo server

After this, you will have a version of the website running on port 4000. The whole thing took me about a minute, mostly for the "npm install" step.  After issuing the command hexo init blog  ("blog" is a directory, you could choose anything else), you will get the following structure:

 Volume in drive C is OS
 Volume Serial Number is F67A-0624

 Directory of C:\Users\Dan.Solovay\testhexo

11/26/2015  04:09 PM    <DIR>          .
11/26/2015  04:09 PM    <DIR>          ..
11/26/2015  04:09 PM                65 .gitignore
11/26/2015  04:09 PM               442 package.json
11/26/2015  04:09 PM    <DIR>          scaffolds
11/26/2015  04:09 PM    <DIR>          source
11/26/2015  04:09 PM    <DIR>          themes
11/26/2015  04:09 PM             1,477 _config.yml
               3 File(s)          1,984 bytes

The .gitignore is there in case you want to set up a git repository for your blog. It ignores the built in and generated stuff, so just your markdown files and configuration is recorded.  package.json includes the Node modules that make that power hexo. They will get loaded when you run "npm install".  _config.yml is where you define site wide options, like the name of your site, and the location where you want to deploy to. Your posts go in the "source" directory as Markdown files, and the generated HTML will go in a "public" folder. 

Basic Workflow
You can generate a new post by typing

hexo new post "My Post Name"


hexo new draft "My Post Name"

These create Markdown files either in source/_posts or source/_drafts.  Drafts will not get deployed to your destination site if you do a deploy (more on that later), and can get turned into posts by typing

hexo publish post "My Post Name"

This moves it over to the _posts folder, and adds a date field to the page header, if one is not already there.  But the post is still in  Markdown.  The HTML gets created by typing:

hexo generate

Again, you can type "hexo server" to launch a server at port 4000, and "hexo server --drafts" to include draft posts (useful for double checking Markdown conversion, and so forth.)

To give you a flavor of the power of editing in Markdown, here is a side by side of a test post in Markdown and what was generated using the preinstalled "landscape" layout.

You can see that the angle brackets in the Markdown were respected, and there was even built in syntax highlighting.  I find the overall look and feel very readable.  This easy of readability really jumps out when we look at an actual post.  Here is a a page of a recent post on my current Blogger layout, and in Hexo.  I think the syntax highlighting of the PowerShell makes the post much more readable. The kicker was how much easier the version on the right was to compose.  Less work, better results.  That is the power of using current tooling, my friends.

Deploying to Github

Of course, you need to get your content to some place where people can see it. One compelling option is Github pages. Every github user gets a free website at URL, which is supported by a repository of the same name.  In other words, if your github user account name is "myname", and you create a repository called "", and HTML pages there will be served by Github at the URL And since the site is supported by a repo, you get versioning for free, at least for the generated HTML.

With a very little bit of setup, you can push to this repo with a single command.  First, you need to install the Node module "hexo-deployer-git".  Then,  in your _config.yml file, go to the section Deployment,  and set the type of deployment to "git" and put the Url of the git repository for the destination site. You can also configure the commit message and branch, as described here.

My deployment settings are:

# Deployment
## Docs:
  type: git

Now deployment can be handled by Hexo using a simple git push behind the scenes, triggered by the command hexo deploy .  You can use option -g to regenerate the site, which I needed to do to make a backdated post appear (there is probably some updated up to here logic I was bypassing by setting dates in the past).

Next Steps

I expect the full migration process to take me a month or two.  I'd like to pull comments over, and this is not supported out of the box from DISQUS.  I am working on getting redirects from my old URLs working, and should blog about that soon.  When things look good, I'll repoint to the new URL (, but will keep my original URL on line. It is free, after all, and it's where I got my start blogging.


  1. Awesome - I'm glad more people are finding Hexo and realizing how nice it is to work with. I read the same post by Kam and moved my blog over: - had similar conclusions as you. Hexo is a really nice tool. Also Markdown pad is nice, but I really like VSCode for editing the markdown, its a great text editor!

  2. I must admit I had only heard of Ghost before from the Node.js blog category but Hexo does look really promising. Good luck with the migration!