Migrate to RunxBuild today!! Deploy More while Spending Less

Calculate your savings
unxBuild

GitHub Blog Theme: How to Pick and Install One That Lasts

Sean

Platform Writer

Sep 30, 2026
10 min read

A GitHub blog theme is a static site generator theme that GitHub Pages builds for you: with Jekyll you set remote_theme in _config.yml and push, and with Hugo you add the theme as a submodule and publish through a GitHub Actions workflow.

GitHub Blog Theme: How to Pick and Install One That Lasts

Most people pick a theme from a screenshot and find out three weeks later that it needs a plugin Pages will not run, or a build step Pages does not perform. The theme decides more than colour. It decides which generator you are married to, how you write posts, and how painful a migration will be later. This guide covers how to choose, how to install both kinds properly, how to attach your own domain, and where GitHub Pages stops being the right home for a blog that is growing up.

Table of contents

Choose the generator before the theme

GitHub Pages serves static files, and it can build two kinds of source itself or through Actions. Jekyll is the native option: push Markdown and a config file, and Pages builds the site with no workflow to write. Hugo, Astro, Eleventy and the rest work too, but you build them in a GitHub Actions workflow and publish the output.

That split should drive your choice. If you want the shortest path from a Markdown file to a live URL, Jekyll themes are the path of least resistance, and thousands are free. If you want faster builds, a single binary with no Ruby toolchain, and a large base of blog-focused themes, Hugo is the better long-term bet, at the price of one workflow file. Pick based on how you like to work, not on the prettiest demo.

Then read the theme’s README before you fall for the demo. You are looking for four things: when it was last updated, whether it lists a minimum generator version, whether it needs plugins beyond the ones Pages allows, and whether its features include the ones you actually use, such as tags, an RSS feed, code highlighting, search and dark mode. A theme that ships a nice homepage but no tag pages will hurt the moment you have forty posts.

A last filter is the blog versus docs distinction. Some themes are built for documentation with a sidebar tree, and forcing them into a chronological blog is a fight you lose. Choose one built for the shape of content you are going to write.

Install a Jekyll theme with remote_theme

GitHub Pages supports a fixed list of themes by name, including Minimal, Cayman and Slate, and the default is Minima. Those are fine for a plain page. For anything better looking, most people use a theme hosted in its own repository, and Pages can load it directly with the remote theme plugin.

# _config.yml
remote_theme: mmistakes/minimal-mistakes
plugins:
  - jekyll-remote-theme
  - jekyll-feed
  - jekyll-seo-tag
  - jekyll-sitemap

title: My Blog
baseurl: ""
url: "https://yourname.github.io"
minimal_mistakes_skin: default

Commit the file, and Pages builds the site. If you want to run it locally first, install Ruby and Bundler, add the github-pages gem to your Gemfile so your local versions match what Pages runs, and serve it.

bundle install
bundle exec jekyll serve --livereload

Customise by overriding, not editing. Create a file in your own repository with the same path as one in the theme, such as _includes/footer.html or a file under _sass, and Jekyll uses yours instead. That keeps you compatible with upstream updates. Editing a copy of the whole theme means you own every future bugfix yourself. The GitHub documentation on adding a Jekyll theme covers the supported themes and the remote option, and the Jekyll personal website guide walks through a full example.

Install a Hugo theme and build it with Actions

Hugo themes are folders you drop into your project, and the cleanest way is a git submodule so the theme stays a tracked dependency instead of a pile of copied files.

hugo new site myblog
cd myblog
git init
git submodule add https://github.com/adityatelange/hugo-PaperMod themes/PaperMod
echo "theme = 'PaperMod'" >> hugo.toml
hugo new content posts/first-post.md
hugo server -D

Pages does not run Hugo on its own, so set the Pages source to GitHub Actions in the repository settings and add a workflow that builds the site and uploads it as the Pages artifact. Remember to check out submodules in the workflow, because forgetting it is the single most common reason a Hugo theme works locally and produces a blank site on GitHub.

name: Deploy Hugo site
on:
  push:
    branches: [main]
permissions:
  contents: read
  pages: write
  id-token: write
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
      - uses: peaceiris/actions-hugo@v3
        with:
          hugo-version: 'latest'
      - run: hugo --minify
      - uses: actions/upload-pages-artifact@v3
        with:
          path: ./public
  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
    steps:
      - uses: actions/deploy-pages@v4

Set baseURL in your Hugo config to the final address, or every asset link comes out wrong. The Hugo GitHub Pages tutorial goes through this end to end if you want the longer version. Theme updates are another difference from Jekyll: a submodule is pinned to a commit, so nothing changes until you deliberately run git submodule update —remote and review the diff. That is safer than an unpinned remote theme, which can change under you between two builds, and it is worth doing for any site you care about.

Add a custom domain properly

A username.github.io address is fine for a hobby project and a mild embarrassment for a business. Pages supports custom domains with free HTTPS, and setting one up is mostly DNS.

In the repository’s Pages settings, enter your domain. For a subdomain like blog.example.com, create a CNAME record pointing at yourname.github.io. For an apex domain like example.com, create four A records pointing at the addresses GitHub publishes in its documentation, and optionally matching AAAA records for IPv6. Then tick Enforce HTTPS once the certificate has been issued, which can take a little while after the DNS change propagates.

Type   Name   Value
CNAME  blog   yourname.github.io

# apex domain: four A records to the IPs in GitHub's Pages docs
A      @      <ip 1>
A      @      <ip 2>
A      @      <ip 3>
A      @      <ip 4>

Two details save an evening. If you publish from a branch, Pages writes a CNAME file into the repository, and a Jekyll or Hugo build that does not include that file in its output can wipe the setting on the next deploy. With an Actions workflow, the domain lives in settings instead, so nothing is lost. And do not add the domain before the DNS exists, because the check will fail and the error message is unhelpful. Getting your blog indexed once it is on a real domain is a topic of its own, and the GitHub Pages SEO guide covers sitemaps, canonical URLs and the settings that quietly hurt rankings.

The limits of GitHub Pages

Pages is generous for what it is, and the limits are worth knowing before you build on them. Published sites are capped at 1 GB, there is a soft bandwidth limit of about 100 GB a month, and builds are soft-limited to around ten per hour. The terms also say Pages is not for running an online business, an e-commerce site or software as a service, which rules out a store and rules out a paid product front end.

The technical limits bite earlier. There is no server-side code at all, so a contact form, a comment box or a newsletter signup needs a third-party service. You cannot set response headers, so you cannot add a strict Content-Security-Policy or tune cache lifetimes. You cannot write redirect rules, so restructuring your URLs means client-side redirect pages that search engines treat poorly. Every push to a branch is either the live site or nothing, so there are no preview URLs for reviewing a post before publishing.

Jekyll on Pages has a further restriction: only an allow-list of plugins runs when Pages builds the site for you. A theme that needs anything else has to be built in Actions instead, which is fine, but it means the simplicity you chose Jekyll for is gone.

None of this is a reason to avoid Pages for a personal blog. It is a reason to be honest about which of these features your blog will eventually need.

When to move off GitHub Pages

Move when the blog starts wanting things a file server cannot do. The signs are consistent: you want to set security headers, you need real redirects after a URL restructure, you want a preview link to send an editor, you have outgrown the bandwidth allowance, or the blog now sits beside a product that needs an API and a database.

The good news is that a static blog is the easiest thing to move. Your content is Markdown in a repository, your theme is a dependency, and the output is a folder. Nothing in your source is tied to Pages, apart from the base URL and the DNS records you will repoint. A static host that builds from your repository runs the same build command you already have and publishes the same folder.

Keep the content in Git, keep the theme upstream, and treat the host as replaceable. That is the whole strategy, and it means the choice you make today is not the one you are stuck with.

How this fits the rest of the stack

When the move comes, the destination for a Jekyll or Hugo blog is a static site: connect the repository, set the build command to bundle exec jekyll build or hugo —minify, and publish the _site or public folder. You get custom domains and certificates, headers, redirects and rewrites, with 120GB of bandwidth included. The RunxBuild hosting calculator shows what that looks like against a blog that also has a small API or a database behind it. Connect the repo from the RunxBuild dashboard, and see the static site documentation and the redirects guide for the parts Pages could not do. Your posts stay in Git either way, which is the point. If the redirect and header rules are what pushed you off Pages, they are a few lines of configuration rather than a workaround, and the old pages keep their search rankings.

Useful related references:

FAQ

How do I add a theme to a GitHub Pages blog?

For Jekyll, set theme in _config.yml for a supported theme, or set remote_theme to owner/repo and list jekyll-remote-theme under plugins for any theme hosted on GitHub. For Hugo, add the theme as a git submodule under themes, set the theme name in your config, and build with a GitHub Actions workflow.

What is the best theme for a GitHub blog?

For Jekyll, Minimal Mistakes and Chirpy are widely used and actively maintained, and Beautiful Jekyll is simple to start with. For Hugo, PaperMod is a common choice for a clean blog. Check the last update date, required plugins and whether tags, RSS and search are built in before you commit.

Can I use a custom domain with a GitHub Pages blog?

Yes. Enter the domain in the repository Pages settings, then create a CNAME record for a subdomain or A records for an apex domain at your DNS provider. Once DNS resolves, enable Enforce HTTPS and GitHub issues a free certificate. Setting DNS before the domain in settings avoids most errors.

Is GitHub Pages free for blogs?

Yes for public repositories on a free account, and private repositories need a paid GitHub plan. There are soft limits: a 1 GB site size, about 100 GB of bandwidth a month and around ten builds an hour. The terms exclude commercial online stores and software as a service.

Can I use Hugo on GitHub Pages?

Yes, but Pages does not build Hugo for you. Set the Pages source to GitHub Actions and use a workflow that checks out submodules, runs hugo, and uploads the public folder as the Pages artifact. Forgetting to check out submodules is the usual cause of an empty site.

#github blog theme#GitHub Pages#Jekyll themes#Hugo themes#custom domain