A github.io blog template is a Jekyll theme applied to a GitHub Pages repository named username.github.io. The fastest route is a template repository for a theme like Minimal Mistakes or Chirpy: use the template, edit _config.yml, push, and the blog is live at your github.io address within a minute. The remote_theme setting lets you use a theme without copying its files into your repository, which keeps updates easy. Pages builds Jekyll for free with a fixed plugin list; the moment you need a plugin outside that list, a custom build or anything that is not a static page, you have outgrown it, and that moment arrives sooner than the tutorials suggest.
The search results are a GitHub topic page with two thousand theme repositories and the official docs on adding a theme. Neither says which theme to pick or what happens after. This post picks for you, shows the setup that avoids the fork-and-drift problem, and is honest about the ceiling, because a blog that started on Pages usually needs to move once it is popular enough to matter.
Table of contents
- What github.io actually gives you
- Choosing a template
- The setup that avoids forking
- Writing posts and the front matter that matters
- The point where you outgrow Pages
- Moving to a real static host
- How this fits the rest of the stack
- FAQ
What github.io actually gives you
A repository named username.github.io, when Pages is enabled, is served at https://username.github.io. If the repository contains a Jekyll site, GitHub builds it on every push using its own Jekyll installation. If it contains plain HTML, it serves that. Either way the hosting is free, the certificate is automatic, and a custom domain is a CNAME file and a DNS record away.
The constraints come with the free build. GitHub’s Jekyll runs a fixed set of plugins: pagination, feed, SEO tags, sitemap, a few more. Anything else is ignored. The Jekyll version is whatever GitHub runs, which lags releases. And the build is Jekyll or nothing; a Hugo or Eleventy site on Pages needs a GitHub Actions workflow to build it and push the output.
For a personal blog with posts and a few pages, none of that matters. That is the case github.io is for.
Choosing a template
Two thousand themes is not a choice, it is a search problem. Narrow it with three filters.
- Is it maintained? Look at the last commit date and the open issues. A theme with no commits in two years will break on the next Jekyll change GitHub rolls out.
- Is it a template repository or a gem? Template repositories give you a working site in one click. Gem-based themes install as a dependency and work with remote_theme, which is the cleaner setup. The best themes offer both.
- Does it do the four things a blog needs? Posts with dates and tags, a feed, an archive or tag pages, and a layout that reads well on a phone. Everything else is decoration.
Three that pass all three filters, in order of how much they do: Minima, the default theme, which does exactly the four things and nothing else; Minimal Mistakes, which adds navigation, author sidebar, galleries and a dozen skins; and Chirpy, which adds dark mode, a table of contents, search and categories out of the box. For a first blog, Minima or Chirpy. Minimal Mistakes when you want a documentation-site feel.
The setup that avoids forking
Most tutorials say fork the theme. Do not. A fork copies every file of the theme into your repository, and from then on theme updates are a manual merge against your edits. The remote_theme setting uses the theme from its repository at build time and keeps your repository down to content and config.
# _config.yml
remote_theme: cotes2020/jekyll-theme-chirpy
plugins:
- jekyll-remote-theme
- jekyll-feed
- jekyll-seo-tag
- jekyll-sitemap
title: Your Blog
url: https://username.github.io
Your repository then needs only _config.yml, a _posts folder, an index page, and any layout files you specifically want to override. To override one file from the theme, copy that file into the same path in your repository; Jekyll uses yours first.
Some themes, Chirpy included, ship a starter template repository that already has this wiring plus a GitHub Actions workflow. Use the template, then push. The first build takes a minute or two; later ones are faster.
Writing posts and the front matter that matters
Posts are Markdown files in _posts named YYYY-MM-DD-slug.md. The date in the filename is the publish date and the URL. The front matter at the top of the file is where the theme reads title, tags and layout.
---
title: Why I Moved My Blog
date: 2026-09-16 09:00:00 +0000
categories: [writing]
tags: [blog, jekyll]
---
The post starts here.
Two habits pay off later. Keep the slug short and stable, because it becomes the URL and changing it breaks inbound links. And put images in an assets folder with a predictable path rather than uploading them through the GitHub web editor, which puts them wherever it likes.
For a custom domain, add a CNAME file containing the domain, set the DNS at your registrar, and enable Enforce HTTPS in the repository settings once the certificate is issued.
The point where you outgrow Pages
Pages is a fine home for a blog until one of these happens, and for a blog that gets read, one of them eventually does.
- You need a plugin that is not on the list. Image processing, a custom tag, a different Markdown renderer. The workaround is building in GitHub Actions and pushing the output, at which point Pages is just a file host with a build step you maintain.
- You need anything dynamic. Comments, a newsletter form that stores addresses, a search index built at runtime, a members area. Pages serves files. It cannot run a process.
- You want redirects and headers. Old URLs need to redirect, security headers need setting. Pages supports neither; the redirect-from plugin generates meta refresh pages, which is a workaround, not a redirect.
- Traffic. Pages has a soft bandwidth limit of 100GB a month and a guideline against commercial use. A popular post with images can approach the first; a blog that sells anything falls under the second.
None of these is a reason to avoid starting on Pages. They are the signals that it is time to move, and the move is easy because a Jekyll site is a repository that any static host can build.
Moving to a real static host
The same repository, built by a host that runs your Jekyll or any other generator with any plugin, is the natural next step. The two values that matter are the build command and the output folder; for Jekyll, bundle exec jekyll build and _site.
On RunxBuild, a static site takes those two values, builds from the repository on every push, and adds the things Pages lacks: real redirects, response headers, a custom domain with a certificate, and 120GB of bandwidth included with a stated price after; static sites on RunxBuild has the setup. When the blog needs the dynamic part, a form that stores, a search service, the service runs beside the site on the same platform rather than on a different vendor.
How this fits the rest of the stack
Start on Pages with a maintained theme and remote_theme, write posts, and do not think about hosting until one of the signals above fires. When it does, the repository moves as it is. The RunxBuild hosting calculator shows what a static site plus the first dynamic piece costs so that the move is a number rather than a guess, and the dashboard is where the same repository gets connected to a build that runs on every push.
Useful related references:
- Getting Started With GitHub Pages, and the Exact Point You Outgrow It
- GitHub Pages SEO: What You Can Fix and What You Cannot
- The Best Blogging Platform Is the One You Can Leave
- Static sites on RunxBuild
FAQ
Which Jekyll theme is best for a github.io blog?
Minima if you want the plain default, Chirpy if you want dark mode, search and a table of contents out of the box, Minimal Mistakes if you want a documentation-style layout with many skins. All three are maintained and work with remote_theme.
Should I fork a theme or use remote_theme?
Use remote_theme. A fork copies the theme’s files into your repository and makes every theme update a manual merge. remote_theme pulls the theme at build time and your repository stays as content and config, with only the files you deliberately override.
Why is my GitHub Pages build failing after adding a plugin?
GitHub Pages only runs a fixed list of Jekyll plugins. Any other plugin is ignored or causes a build error. Either drop the plugin, or build the site in GitHub Actions and publish the output folder instead of letting Pages build.
Can I use a custom domain with a github.io blog?
Yes. Add a CNAME file to the repository containing the domain, create the DNS records at your registrar pointing at GitHub Pages, and enable Enforce HTTPS in the repository settings once the certificate is issued.
When should I move a blog off GitHub Pages?
When you need a plugin outside the supported list, anything dynamic such as a form that stores data, real redirects and headers, or when traffic approaches the 100GB monthly guideline. A Jekyll repository moves to any static host that builds from git with no changes to the content.