GitHub Pages Jekyll Theme: Complete Setup Guide (2026)
Everything you need to know about using Jekyll themes on GitHub Pages — supported themes, remote themes, deployment, and troubleshooting common issues.
GitHub Pages is the most popular way to host a Jekyll site — it’s free, integrates directly with your repository, and rebuilds automatically on every push. This guide covers everything you need to set up a Jekyll theme on GitHub Pages correctly.
How GitHub Pages Builds Jekyll Sites
When you push to a GitHub Pages repository, GitHub runs Jekyll automatically on their servers. This means:
- No build command needed
- No server to manage
- Free HTTPS via GitHub’s CDN
- Automatic rebuilds on every commit
The limitation: GitHub Pages only supports a specific set of plugins. Themes that require unsupported plugins won’t build on GitHub Pages directly — you’ll need to use GitHub Actions instead.
Option 1: Use an Official GitHub Pages Theme
GitHub maintains 12 official themes that work on GitHub Pages without any plugin setup:
To use one, add to _config.yml:
theme: jekyll-theme-minimal
That’s it — no Gemfile changes needed for GitHub Pages.
Option 2: Use Any Theme via remote_theme
The jekyll-remote-theme plugin (supported by GitHub Pages) lets you use any public GitHub repository as a theme:
Step 1: Update _config.yml
remote_theme: mmistakes/minimal-mistakes
plugins:
- jekyll-remote-theme
Step 2: Update Gemfile
source "https://rubygems.org"
gem "github-pages", group: :jekyll_plugins
gem "jekyll-remote-theme"
Step 3: Push to GitHub
git add .
git commit -m "Set up Jekyll theme"
git push
GitHub Pages builds your site automatically. Check the Actions tab in your repository to monitor the build.
Option 3: Deploy with GitHub Actions (Recommended for Advanced Themes)
For themes like Chirpy, Hydejack, or Just the Docs that use unsupported plugins, use GitHub Actions to build and deploy:
Step 1: Create .github/workflows/pages.yml
name: Deploy Jekyll site to Pages
on:
push:
branches: ["main"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.1'
bundler-cache: true
- name: Build with Jekyll
run: bundle exec jekyll build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Step 2: Enable GitHub Pages via Actions
Go to Settings → Pages → Source and select GitHub Actions.
Setting Up Your Repository
Repository naming
| Goal | Repository name |
|---|---|
| User/org site | yourusername.github.io |
| Project site | Any name (served at yourusername.github.io/repo-name) |
Essential _config.yml settings for GitHub Pages
url: "https://yourusername.github.io"
baseurl: "" # Leave empty for user sites, "/repo-name" for project sites
title: "My Site"
author:
name: "Your Name"
email: "you@example.com"
Common mistake: Setting
baseurlincorrectly causes broken asset links. For user sites (yourusername.github.io), always setbaseurl: "".
Popular Jekyll Themes That Work on GitHub Pages
| Theme | Type | GitHub Pages Compatible |
|---|---|---|
| Minimal Mistakes | Blog/Portfolio | ✓ via remote_theme |
| Chirpy | Blog | ✓ via Actions |
| Just the Docs | Documentation | ✓ via Actions |
| Beautiful Jekyll | Blog | ✓ via remote_theme |
| Jekyll Now | Blog | ✓ direct fork |
| Hacker | Developer | ✓ official theme |
| Minimal | Personal | ✓ official theme |
Troubleshooting Common GitHub Pages Issues
Build fails with “Dependency Error”
The theme uses a plugin not supported by GitHub Pages. Switch to GitHub Actions deployment.
Site builds but CSS is broken
Check your baseurl setting. For project sites it must be /repo-name, for user sites it must be "".
Changes not appearing
GitHub Pages can take 1–2 minutes to rebuild. Check the Actions tab for build status.
remote_theme not loading
Make sure jekyll-remote-theme is listed under plugins: in _config.yml and in your Gemfile.
References
- GitHub Pages Documentation
- GitHub Pages Supported Versions
- jekyll-remote-theme
- GitHub Actions for Jekyll
Setting up a custom domain
A custom domain transforms yourusername.github.io into yourname.com. Setting it up takes about ten minutes and requires access to your domain’s DNS settings.
Step 1: Add the domain in GitHub
Go to your repository Settings → Pages → Custom domain, enter your domain (e.g. www.example.com or example.com), and save. GitHub will add a CNAME file to your repository automatically.
Step 2: Update your DNS
For an apex domain (example.com), create four A records pointing to GitHub’s IP addresses:
185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153
For a www subdomain, create a CNAME record pointing to yourusername.github.io.
Step 3: Update _config.yml
url: "https://www.example.com"
baseurl: ""
DNS propagation can take up to 48 hours, though it is usually complete within an hour. GitHub Pages automatically provisions an HTTPS certificate via Let’s Encrypt once the DNS records resolve correctly. Enable Enforce HTTPS in your repository settings after the certificate is provisioned.
Step 4: Update your CNAME file
If you commit the CNAME file manually, ensure it contains only your domain name, with no trailing slash:
www.example.com
Commit this file to the root of your repository.
Managing multiple environments
Many Jekyll users want to test changes locally before pushing to GitHub Pages. The most important _config.yml setting to get right across environments is url.
Use a _config.local.yml override file for local development:
# _config.local.yml
url: "http://localhost:4000"
baseurl: ""
Run locally with:
bundle exec jekyll serve --config _config.yml,_config.local.yml
The second config file overrides values from the first. This prevents your local build from generating absolute URLs pointing to your production domain, which would break internal links during development.
For GitHub Actions builds, set JEKYLL_ENV=production in your workflow to enable production-only features like analytics:
- name: Build with Jekyll
run: bundle exec jekyll build
env:
JEKYLL_ENV: production
Protecting your main branch
Once your site is live, accidental commits to main can break your production site immediately. Protect the branch in GitHub to require pull request reviews before merging:
Go to Settings → Branches → Add branch protection rule. Set the branch name pattern to main, enable “Require a pull request before merging”, and optionally require status checks (like a successful Jekyll build) to pass.
With branch protection, you can develop on a feature branch, push it to GitHub, and confirm the site builds correctly via the Actions tab before merging to main. This prevents broken deployments from reaching visitors.
Optimising build time with caching
GitHub Actions build time grows as your site gains more pages and posts. Bundler gem caching is the single most effective optimisation — it avoids re-downloading all gems on every build:
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.1'
bundler-cache: true # ← caches gems in .bundle/
For JavaScript-heavy setups (Tailwind CSS, Alpine.js via npm), cache the node_modules directory:
- name: Cache node modules
uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
With both caches warm, a typical Jekyll build on GitHub Actions completes in 30–90 seconds depending on site size.
Understanding GitHub Pages plugin restrictions
The key constraint when using GitHub Pages’ built-in builder (without GitHub Actions) is the plugin allowlist. GitHub Pages runs Jekyll in --safe mode, which disables all plugins not on the approved list.
The allowed plugins include jekyll-feed, jekyll-seo-tag, jekyll-sitemap, jekyll-redirect-from, jekyll-paginate, jekyll-mentions, jekyll-optional-front-matter, and a few others. The full list is at pages.github.com/versions.
Plugins not on this list — including jekyll-paginate-v2, jekyll-algolia, most custom generators, and any plugins you write yourself — require GitHub Actions to build.
The practical rule: if your Gemfile lists only plugins from the GitHub Pages allowlist, you can use the simple push-and-build workflow. If you need any plugin outside the list, set up GitHub Actions once and enjoy full plugin freedom for the lifetime of the project.
Preview deployments for pull requests
A useful pattern for team blogs or sites with multiple contributors is deploying a preview of each pull request to a separate URL before merging. This lets you review changes in a live environment.
Netlify and Cloudflare Pages both offer this natively and can serve as a deployment target instead of GitHub Pages while keeping your repository on GitHub. Each pull request automatically gets a unique preview URL like https://deploy-preview-42--your-site.netlify.app.
For sites committed to GitHub Pages, the github-pages-preview Action from the marketplace provides a similar capability by deploying to a separate gh-pages-preview branch.
Preview deployments are particularly valuable for CSS changes, layout modifications, and content formatting reviews where seeing the rendered output is much faster than reading a diff.
What to do when builds fail
GitHub Pages build failures appear in two places: the Actions tab in your repository (for Actions-based deployments) and as an email notification to your GitHub account (for the built-in builder).
The most common causes and fixes:
Syntax error in a Liquid template — check for unclosed tags ({% if %} without {% endif %}), mismatched quote marks, or invalid filter names. The build log in Actions shows the file and line number.
Missing plugin in Gemfile — if _config.yml lists a plugin under plugins: that is not in Gemfile, the build fails. Both must be in sync.
Invalid YAML in front matter — YAML is whitespace-sensitive. Tab characters instead of spaces, missing colons, or incorrect indentation cause parse failures. Use a YAML validator (like yaml.me) on any front matter you are unsure about.
Theme not found — if _config.yml specifies theme: some-gem-theme but the gem is not in Gemfile and Gemfile.lock, the build fails. Either add the gem to Gemfile or switch to remote_theme: for GitHub Pages.
File encoding issues — Jekyll expects UTF-8. Files saved with Windows line endings (CRLF) or non-UTF-8 encoding occasionally cause cryptic errors. Your editor’s encoding settings control this.
GitHub Pages is an excellent hosting choice for Jekyll sites at every scale — from a personal blog to a company documentation site. The free tier, HTTPS, CDN delivery, and tight Git integration make it uniquely convenient. Understanding the plugin restrictions upfront and choosing between the built-in builder and GitHub Actions based on your theme’s needs will prevent most deployment frustrations before they happen. Browse JekyllHub’s theme collection with a “GitHub Pages Compatible” filter to find themes ready to deploy with a single push.
Choosing between GitHub Pages and alternative hosts
GitHub Pages is the natural choice for many Jekyll users, but it is not the only option. Alternatives like Netlify, Cloudflare Pages, and Vercel offer more features with similar or lower cost.
Netlify’s free tier supports GitHub-integrated deployment, PR preview URLs, form handling without JavaScript, edge functions, and _redirects file processing — all features that GitHub Pages lacks. If your Jekyll site uses jekyll-netlify-redirects or Netlify Forms for your contact page, deploying to Netlify rather than GitHub Pages removes the friction of working around platform limitations.
Cloudflare Pages offers unlimited bandwidth even on the free tier (GitHub Pages limits you to 100GB/month) and builds your Jekyll site in a global CDN with edge caching. For high-traffic sites or sites that embed large assets, this matters.
The trade-off is that GitHub Pages is tightly integrated with the repository — zero configuration for standard use cases, no separate deployment service to manage, and immediate status feedback in the same GitHub interface where you work. For personal blogs, documentation sites, and portfolios with modest traffic, GitHub Pages is genuinely the best choice. For sites with complex redirect rules, form handling, or very high traffic, consider Netlify or Cloudflare Pages from the start to avoid migrating later.
Whichever host you choose, the Jekyll site itself is identical — the same _posts/, _layouts/, and _config.yml. Only the deployment configuration changes. This is one of Jekyll’s genuine strengths as a platform: your content and theme are completely portable between hosting providers.