Migration of the Blog to Hexo

I have ultimately decided to transition my blog from a dynamic Typecho website to a static Hexo platform 😳.

Rationale for Migration

My personal blog was established on May 12, 2015, at precisely 8:39:39 PM on a Tuesday. Since then, I have been using Typecho due to its lightweight, simplicity, efficiency, and the fact that it aligns perfectly with my requirements.

However, after Typecho released its official 1.0 version in October 2014, it took them three long years to release version 1.1 in October 2017. It truly embodies the proverb, “Good things come to those who wait” 😒.

From 2015 to 2021, there was no shortage of tinkering: themes, plugins, optimizations, and eventually, I open-sourced the stable parts of what I had developed. I was also invited to join the plugin development team at Typecho Fans, and, naturally, I continued to maintain the open-source projects I had initiated 👌.

After undergoing numerous endeavors, I realized that it was time to reevaluate the core purpose of my blog: to curate and share content, rather than investing excessive time and energy into peripheral elements.

Is Typecho still suitable for me? Indeed! Through continuous refinement and optimization, Typecho was able to satisfy the majority of my requirements. However, it requires self-maintenance, which means I must invest time and effort into its upkeep. Although I can deploy it in under a minute with Docker, I still need to rely on a dedicated server to ensure its smooth operation. While I have no shortage of servers, what I truly lack is the energy.

In essence, there is an ultimate form: developing a static site generator to convert Typecho into a static site. But why reinvent the wheel when mature static blog engines are readily available?

Selection of Blog Engine

Since I’ve decided to migrate to a static blog, I compared the maturity, activity, and popularity of various options from Site Generators. Ultimately, I chose Hugo and Hexo.

Choosing between the two was straightforward. I set them both up, tested them, and found that static blogs are relatively similar, with low migration costs between them.

Hugo performs impressively in terms of performance, owing to its underlying language. Besides that, Hugo and Hexo are quite similar in terms of deployment within the JAMstack ecosystem.

The significant difference lies in their theme and plugin ecosystems. Hugo’s highest-ranked theme is olOwOlo/hugo-theme-even, which is a port from Hexo. After extensive searching, I found no theme that could compete with next-theme/hexo-theme-next in terms of completeness, maturity, activity, and ongoing maintenance. Unfortunately, Hugo has many beautiful themes that were eventually abandoned (a pity): dillonzq/LoveIt.

Hexo is developed in JavaScript, primarily by front-end enthusiasts.

Hugo, on the other hand, is written in Go, predominantly by back-end professionals.

Which one would you consider more reliable?

V2EX User

In the end, after comparing the two, Hexo aligns better with my requirements: comprehensive, mature, and consistently maintained.

I have entrusted the compilation of Hexo to GitHub Actions, and according to Hexo’s official benchmark results, it takes 15 seconds to compile 300 articles. I’ll address the performance when I reach 300 articles✍️.

Practical Migration

Now that Hexo has been chosen, the next step is selecting a theme.

The field of front-end technology is rapidly evolving. Without long-term maintenance, stable user experiences cannot be guaranteed, especially with the emergence of new browser features.

For example, some browsers offer native “image lazy loading,” which requires no JavaScript for implementation. Themes need to be adapted to this feature.

PS: The development version of typecho-markdown automatically supports this feature during image rendering👻.


I have optimized Typecho themes myself, and I know that there is no end to refining details. Considering my requirements, the ultimate theme preferences are: maturity > continuous maintenance > feature completeness.

I eventually chose next-theme/hexo-theme-next and ppoffice/hexo-theme-icarus and tested them both.

From the perspective of “likelihood of resemblance,” Icarus has a higher probability of similarity, but it is less customizable. Customization requires direct modification of the theme source code. Hexo 5.0, however, supports theme installation via NPM, making direct modification impossible unless the theme source code is included in the repository. This could lead to issues with future updates and potential conflicts.


Ultimately, I chose NexT. It provides dedicated configuration and injection APIs for customizing page layouts and styles. Despite a slightly higher chance of “resemblance,” this theme is undeniably robust👏.

The subsequent steps are routine operations with abundant resources and some outdated ones. Here are some notes:

  1. Configure GitHub Actions to automatically compile and output to GitHub Pages upon code push. Please note that only Pro users can configure private repositories for GitHub Pages.
  2. Ensure to place the CNAME file in the source directory; otherwise, the CNAME configuration will be lost after each compilation. The CNAME content should match your desired custom domain.
  3. Opt for Utterances for comments; the comment repository must be public.
  4. Avoid using the GitHub + jsDelivr solution for image resources, as jsDelivr has updated its terms to explicitly state that it should not be used as an image host.
  5. Consider Backblaze B2 + Cloudflare for image hosting in cases without record-keeping requirements. If record-keeping is necessary, opt for a domestic CDN for convenience, affordability, and speed.


The old blog will still exist, but it may no longer receive updates. I will review the contents of my drafts from the past two years and publish them on the new blog.

There is no way to migrate comments, nor is it necessary since comments are meaningful only when associated with the original articles.

Performance optimization is an ongoing task. I plan to migrate to a domestic CDN soon. Static files are a breeze; deploying them to a CDN is both convenient and cost-effective.

Recently, I upgraded my Docker Images to PHP8, also configuring JIT. After running for a while, I have encountered no issues. I plan to open-source a complete Docker deployment and data backup solution, the thought process is available here.