Deploy a Hexo blog to Github Pages

Hexo is a powerful static website generator that can be combined with Github Pages to run a personal blog. This pairing is a convenient, performant and free blogging platform that is very flexible and relatively simple.

Most instructions make running this combination more complicated than it needs to be. If you’re already using Github to publish your Hexo blog, read on to learn how to update your workflow and eliminate some plugins.

The background

Github Pages content can come from one of 3 locations:

  • master branch of <username> repository
  • a gh-pages branch from your repository
  • a docs subdirectory

Most existing tutorials guide you to create a new repository according to the first option. If you do that you probably end up with 2 repos like I did:

By default Hexo will generate content into a folder called public. This is configurable via the public_dir setting in _config.yml, so conveniently I could enable Github Pages using the docs subdirectory on my poweredbyjeff repo and do away with one repo. This also has the advantage of allowing me to publish other static websites using different repositories on Github Pages.

If you look carefully at the Github Pages documentation however, there’s a limitation:

If your site is a User or Organization Page that has a repository named <username> or <orgname>, you cannot publish your site’s source files from different locations.

If you blinked and missed it, once you have a repository you can’t use the docs/ folder on any repos. So make sure you disable/rename that existing repo if you’re using it.


So if you’re using Hexo and Github Pages but publishing on <username> repositories, here’s how you convert.

  • On Github (step 1):
    • Create a new repository to store both your Hexo instance and generated website (I suggest naming after your website)
    • Note down the repo address for later.
  • In your Hexo folder (step 2):
    • Remove existing conflicting plugins:
      • npm uninstall hexo-generator-cname hexo-deployer-git
      • Remove related plugin configuration in _config.yml
    • Add the CNAME file (no extension, all uppercase) in the source folder. The contents of this file should be the domain of your website, e.g.
    • Set public_dir: docs in _config.yml.
    • Add the Hexo folder to git, add Github repository created in Step 1 as origin and push to origin.
  • Back on Github (step 3):
    • Disable Github Pages on your existing <username> repository
    • Rename that repository (or delete it if you’re super confident)
    • Enable Github Pages on the repository created in Step 1 and choose the master branch /docs folder option.
    • Eat cake.


  • Source is now stored in the same Github repository as the generated website
  • Do not need hexo-generator-cname or hexo-deployer-git plugins
  • Deploy is simply push to Github (which coincidentally backs up your source)

Feel free to leave comments or questions below. Enjoy!