Building a Hexo theme: postmortem

Recently I’ve had a desire to start blogging again, to help me reflect as I work on projects. It’s a hobby I’ve explored since my exposure to the internet over a decade ago, and I’ve always considered myself a casual blogger. In the past, I’ve used platforms like WordPress and Blogger for personal blogs that usually revolved around projects. This time, I’ve been compelled to start branding my own name and taking ownership of my internet presence. To this end, I wanted to build a blog for myself so I’d have full control and ownership of both the written content and the supporting code of my blog. Originally, I was looking into writing my own blogging platform in React, but ultimately I have no interest in building a product from scratch when there are already several great open source options. There was no reason to reinvent the wheel in this case!

If you’re not familiar with templating frameworks, they are able to generate HTML markup via various templating languages. For this theme I used, EJS (Embedded JavaScript). Templating means you can write a portion of your site (like a header or a footer) only once, and reuse the same code in multiple parts of your website. This creates a static site that can be easily extended and modified without having to make duplicate changes.

At first I considered a generator like Jekyll, but I really wanted to work on a project in JavaScript. There was a JS port named Heckle, but it wasn’t complete and I didn’t want to pick up an incomplete framework for my polished blog. Ultimately, I picked Hexo as the platform on which to build my new blog. There were a few major points that made it an easy choice for me:


  • Markdown support for easy and consistent post styles
  • Generates files very quickly
  • Very extensible via plugins
  • Highly customizable via themes
  • Customizable URLs for SEO optimization
  • Built in Node.js, a JavaScript runtime environment

Hexo isn’t perfect, however. There are some things about it which weren’t apparent at first, but later surfaced as annoyances:


  • Spotty documentation that’s missing important details or instructions
  • No built-in HTML beautification means EJS templates structured for JS readability create ugly HTML markup
  • It has a small community of developers across several languages, which makes its development difficult to track

Starting out

I wanted to build a theme in Bootstrap 4 that was mobile responsive, SEO-friendly, and full of delicious meta and schema data for search engines. My inspiration was the official Bootstrap 4 blog example template and my goal was to include all of the same functionality in my new custom theme. I didn’t want to copy the theme or have a default Bootstrap look, however, so the final result would be styled for my personal blog.

Unfortunately the documentation for Hexo is spotty at best and is misleading at worst. In the beginning, there were two steps back for each one forward. After some research, I learned how to correctly build a “skeleton” on which the rest of the layout can depend. The result was the layout.ejs file which contains the main site layout used on every page. Site-wide markup like head content and footer scripts are pulled from partials to construct the frame of the site here. If I need to update scripts or styles, I can make one change in one place that’s then reflected everywhere.

Hexo supports different post types, but almost everything can be boiled down to either an archive or an article. The tag.ejs and category.ejs layouts are essentially archived lists of specific tags and categories, so they use the same _partial/archive.ejs partial as archive.ejs to display their contents. _partial/archive.ejs itself is able to index content sorted by categories, tags, and dates, so it’s able to construct any archive-like list needed for the blog. In my personal implementation, these archive lists are included in the sitemap for better indexing. I didn’t include any special features for pages, as my own implementation of this theme was going to be only blog posts. However, pages are supported out of the box.

Schema, OG, and metadata

Once archiving and listing content was handled, I was able to focus on building the actual structure of the blog posts. I had full control over the HTML structure that would house each of my blog posts, which allowed me to go incredibly lean for a fast load time, while also packing in schema data from Each post generates the correct schema tags to pass all of the tests on Google’s Structured Data Testing Tool. You can check out one of my blog posts on the tool to see for yourself how much schema data is packed in an article post. This results in better indexing and understanding of the website by web crawlers.

Every blogger wants their posts to be shared, so my next focus was adding the Open Graph (OG) Protocol to each page. If you’re not familiar with OG, it’s an assortment of meta tags that pass information to social media networks like Facebook and LinkedIn for sharing. This includes the article’s image, title, and description in the sharing card that is displayed on the social network’s feed. Hexo comes with an OG helper, but it leaves much to be desired. To that end, I wrote a new Meta Maker helper for this theme that pulls metadata from the page and the site’s _config.yml files to generate proper tags for each page. It also handles the other important SEO tags like rel=canonical and page titles, and generates the sharing meta tags for Twitter (which doesn’t use OG).

This one script was immediately very useful to me and I’ve since used it on other Hexo projects. In the future, I’m considering expanding its functionality and creating a plugin with additional features, like something akin to Yoast SEO but for Hexo.

Finishing the design

As mentioned on the list of cons above, an issue I immediately encountered was producing human-friendly HTML markup. Because I was designing this theme as a web design and SEO project, it was important to me that the finished result looked beautiful to both the machine and the human. I also wanted to feel encouraged extending any partial if needed, and human-readable markup would assist in debugging any of those features. If I structured my EJS templates to look good in EJS, they produced poorly formatted HTML. When I structured the EJS for beautiful HTML, I still sometimes encountered issues with paragraph tabbing and extra line breaks. This has been discussed before in the context of EJS, so at least I’m not alone with this issue. In the future, I’d probably use a tool like htmltidy to clean up the files after rendering. That way the EJS files can be properly structured for JavaScript readability while still producing human-readable HTML markup, and I wouldn’t have to worry about this tedious element.

Once again, this is a non-issue if you don’t care about the readability of your files, but a goal in this project was producing an incredibly easy-to-use and accessible theme. It was tedious to structure the EJS for ideal HTML, but I learned a lot about EJS in the process.

I wanted the actual design to use similar colors as my main website, which uses violet and pink. My website was designed before Pantone’s 2018 Color of the Year was picked, and seeing a boosted popularity associated with Ultra Violet and Rose Quartz made it an easy decision to keep using those similar colors (with charcoal accents). Like I’ve said prior, I was designing this theme primarily for my own use, so I was liberal in my font choices to better represent a union of both ancient and modern ideas (a theme on which my blog focuses).

Final thoughts

Ultimately, creating the Space Cadet theme taught me a lot about blog design and using a templating framework like Hexo. Prior to this project, I was leaning more heavily toward using server-based solutions for blogging, and was even considering building my own platform with React. However, Hexo has shown me the power of static site generators. I’ve since ported my personal website to Hexo as well. Because everything on this domain is hosted on Google Firebase, using a static solution is very easy! I would encourage others looking for simple website and blog solutions to explore using a tool like Hexo. With libraries of plugins and themes available, it’s easy to get started with little technical knowledge.

Please check out the following link to download the Space Cadet theme for your own Hexo blog:

Download the Space Cadet theme