Replace your CMS with GitHub Pages, Jekyll and Grunt

posted on 23 September 2015 in programming

Warning: Please consider that this post is over 8 years old and the content may no longer be relevant.

For years I’ve used Wordpress to host my site, which has been great but it’s overkill for what I need. I’d be happier to write the HTML myself if it wasn’t such a maintenance pain keeping consistency across all the pages. I hated having to update WordPress continually to ensure my site is secure. In order to keep all my site source in Git I have to synchronise the changes that happen automatically on the server, like updates and uploads / media files back to my working copy to commit them. And it doesn’t enable me to keep any of my content in Git, which is most important, I have to take regular database backups for this.

So in rebuilding this site I’ve found a new platform to host it which supports my workflow properly, GitHub pages. GitHub pages is a great solution to becoming CMS free but still have a maintainable and extensible site. And you’ll be in good company, besides my own site, the Bootstrap, React and Yeoman sites all use GitHub pages.

GitHub Pages

GitHub pages is a free offering from GitHub that allows you to host one website per account and one website per project, you can even use your own domain name. To use your account site, you need to

  • Create a repo named on GitHub (where username is your GitHub username)
  • Push your website files into the master branch
  • Your site will be available on

For a project site you need to

  • Create a new orphaned branch called gh-pages within your project repo on GitHub
  • Push your website files to this branch
  • Your site will be available on

Free static web site hosting at GitHub is great but what makes GitHub pages stand out is Jekyll.


Jekyll is a static site generator, which means it takes templates, pages and data from a convention based folder structure, and turns it into a static site for you. It’s basically what your CMS is doing on every page request, but it does it just once. GitHub pages runs Jekyll on your site by default, but because you probably aren’t clashing with Jekyll’s folder conventions you won’t notice. Jekyll is blog aware, which means it can do a lot of what your Wordpress site can, it understands published and draft posts, tag, categories, permalinks, post listings and excerpts among other concepts.

├── _config.yml
├── _drafts
|   └── on-simplicity-in-technology.markdown
├── _includes
|   ├── footer.html
|   └── header.html
├── _layouts
|   ├── default.html
|   └── post.html
├── _posts
|   ├── 2007-10-29-why-every-programmer-should-play-nethack.textile
├── _data
|   └── members.yml
└── index.html

A typical Jekyll folder structure contains a _layouts folder for your base templates, an _includes folder for partial includes that can be used by layouts or pages, a _config.yaml file which defines site configuration, and other files and folders that contain your site content. Any folder that Jekyll doesn’t recognise is copied verbatim to the static site and you can tell Jekyll to ignore files or folders and not copy them using configuration settings.


layout: posts
permalink: posts/
title: Recent blog posts
{% include header.html %}
<h1>Here’s some of my recent posts</h1>


<!DOCTYPE html>
<html lang="en">
<head><title>{{ page.title }}</title></head>
  {{ content }}

A Jekyll content page will start with Frontmatter, that’s all the code between the 2 rows of hyphens at the start of the file. In the frontmatter you can can define the layout to use, the page title and a permalink for the page among other configuration settings. These will override any settings in the site config (_config.yaml).

  {% for post in site.posts %}
      <a href="{{ post.url }}">{{ post.title }}</a>
      {{ post.excerpt | strip_html }}
  {% endfor %}

Jekyll uses the Liquid templating language developed by Shopify which will feel familiar for anyone who’s worked with handlebars, mustache or angular. Liquid defines tags for flow control and filters for acting on variables

For a static site generator Jekyll is very feature rich and you’ll be surpised what you can accomplish with it. Apart from templates, it supports SASS, extensionless urls, markdown, textile, even custom domains on GitHub pages.

$ gem install jekyll
$ jekyll serve

Configuration file: /Users/paul/Projects/demo/_config.yml
            Source: /Users/paul/Projects/demo
       Destination: /Users/paul/Projects/demo/_site
 Auto-regeneration: enabled for '/Users/paul/Projects/demo'
Configuration file: /Users/paul/Projects/demo/_config.yml
    Server address:
  Server running... press ctrl-c to stop.

But Jekyll isn’t exclusive to GitHub pages, Jekyll comes packaged as a Ruby gem that allows you to install it on your local machine. Once jekyll is installed you can use jekyll build to compile your static site or jekyll serve to compile, spin up a web server and watch the file system for changes.

And there’s another big benefit to running Jekyll locally, plugins! Plugins extend the functionality of Jekyll but unfortunately they aren’t supported by GitHub pages, so if you want to use a plugin you’ll need to build you site locally and push up the resulting _site folder to GitHub.

Some cool Jekyll plugins allow you to implement site search, create tag or category listings and have page redirects.

When you start thinking creatively it’s surprising how much you can do with a static site with no backend. Want comments? Use Disqus. Want emailed forms? Try Simple Form.


And if you’re building locally and pushing the resulting site to GitHub pages, you can get even more creative with your build pipeline using Grunt. You could preform pre Jekyll tasks like bundling and minification, or post Jekyll tasks like pushing the compiled site up to GitHub automatically using grunt-gh-pages.

TL;DR GitHub pages provides free website hosting optionally using your own domain name and will process a Jekyll site for you. Jekyll is a static site generator offering unbeatable performance with a rich feature set that can be extended by plugins. You can extend your Jekyll build using the power of Grunt and automate publishing to GitHub pages.