The GitHub experience

On why I moved from Kirby and chose to build a static site with Hugo

GitHub is one of my favourite websites of all time; Dropbox is perhaps its only competitor. Neither of these would rank high in terms of design but then again the core purpose of both these websites is functionality and, in that regard, they are both at the top of their game. And that is why, as of today, both this website and Physics Capsule run on a combination of Github, Dropbox and Netlify.

Although I have been using GitHub for quite some time now, I had never quite dipped into the console elements involved in Git. Understandably, most would find this laughable; but for long I found great use for GitHub purely as a browser-based code storage and release service that made it easy to track my code and gave my code a safe home on the web—albeit a non-negotiable, extremely public home, at least until recently.

Having once had a taste of deployment from our personal machines, none of us wanted to go back to a browser-based website with a clunky dashboard.

Necessity breeds the acquisition of knowledge. Physics Capsule, one of my favourite side projects, fell by the wayside last year thanks in large part to both my and my fellow co-founder’s weddings falling just months apart. This is perfectly understandable and neither of us complained. There were also some software woes despite us having recently switched hosts and rewritten a lot of the code from the ground up. I saw this as an excellent opportunity to do something radical that would not only shape Physics Capsule but would help us maintain it with greater ease and ensure the stability of the project in the long run.

Hugo and Google Drive

Having given static sites a lot of thought and having carefully watched their development over the years I decided now was a good time to take the plunge. Some of my readers will recall that I moved away from Wordpress and to a flat file CMS called Kirby about two years ago. I have nothing against Kirby except that its v3 license became a bit too costly for me to justify the expenditure and the host of changes going from v2 to v3 put me off. This is not Kirby’s fault—not entirely anyway—but I took this opportuinty to dip my toes into Jekyll and Hugo. I settled with Hugo eventually because of its speed and because I found its ease of use to be on par with Jekyll.

I could find no way of hosting Hugo with my own host without a complex set-up that involved an FTP program. Especially since multiple people write on Physics Capsule, having a version control system was of paramount importance. At the very least we had to have some way of ensuring we were not undoing one another’s changes.

Enter GitHub

I turned to the trusty old GitHub again, realising that, having once had a taste of deployment from our personal machines, none of us wanted to go back to a browser-based website with a clunky dashboard. Indeed I wanted to stay off the browser entirely myself, which meant my usual GitHub habits had to be pushed aside and the console had to come into play.

Installing Git and generating SSH keys

Installing Git was easy. The official website offers a handy package file to install Git on any operating system. Generating SSH keys was a bit more complicated. Below I reproduce a record for posterity (and we all know precisely how long that is in technology years). First, fire up Terminal.app and check if you have an .ssh directory at home with the following command:

cd ~/.ssh

If such a directory exists it should change to that directory and all should be well. If not, Terminal will tell you that no such file or directory exists so you will have to create it yourself. Do that with

mkdir ~/.ssh

then press return and follow it up with

chmod 700 ~/.ssh

And that should have you set up and ready to go. Next, we need to create your RSA code. This is a randomised alphanumeric snippet that will prove to GitHub that you are in fact who you say you are. Naturally, it will be associated with whatever e-mail is associated with your GitHub account. First cd ~/.ssh and then make sure to enter your e-mail address while you copy and paste the command below:

ssh-keygen -t rsa -C "your-github-email@something.com"

At this point if Terminal asks you which file you want to save the key in just hit Return and it will save using standard defaults. It will also ask for a passphrase, you can give it if you like for added security. At this point you should be able to get an Agent ID if you do

eval "$(ssh-agent -s)"

which will confirm that your RSA code has been generated and is ready to use. Also, as a friendly little tip, if you set a passphrase earlier, you can

ssh-add -K ~/.ssh/id_rsa

you can save your RSA ID passphrase to your iCloud keychain for safekeeping and later reference.

So much for your local machine. If Github needs to associate this machine as a trusted source of code pushes to be associated with you, it needs to know this RSA ID. The trouble with an RSA code is that it is quite sensitive. An extra space or line break (or their lack) will simply mean a different code altogether. The safest way to go about letting GitHub know your RSA ID is to copy it via Terminal:

pbcopy < ~/.ssh/id_rsa.pub

Now head to GitHub, log into your account, click on your profile picture (top-right corner), head to Settings → SSH and GPG keys → New SSH key and paste the copied key with the usual +V shortcut. Save it with your device name, or something you can quickly identify as your device, and you are ready to Git.

General Git workflow

With Hugo, node.js and Git installed, and with our Github SSH keys in place, we were ready to deploy Physics Capsule. The public files had already been built, and the site design had been finalised (at least for a version one deploy). We set up an organisation account with GitHub, with physicscapsule.com as a repository, having decided to go fully open source. The final step involved cloning the repo onto our local machines and we were all set, both on GitHub and on our Macs.

Next we had to set up edge serving with Netlify. Getting that set up was easy. I simply updated necessary records with our domain registrar to point to Netlify and set up a custom domain that went live (i.e. the records propagated) within a day. Netlify also took care of our SSL licenses for us.

With continuous deployment, our workflow was simplified to writing articles (and updating core site files once in a while) and pushing changes to our GitHub repo. That meant we never had to open up our browser, stay connected to the internet, log in anywhere, save our work online etc. In fact, I am typing this right now completely offline, on Ulysses, my writing app of choice. Once I am done I will connect to the web when I can, then pull and --rebase my local version to update it with the master branch (this is simply a safety in the interest of version safety), save the markdown file into my cloned repo, and push changes. Netlify will take things forward thereafter.

In practise, once an article is ready, this entire workflow takes less than a couple of minutes—including being able to view changes on the live site. As a cherry on the cake, using Hugo makes this superfast, extremely stable and quite extensible. Plus hugo server --watch -D makes a copy of the website available on our local server with instant updates and no refreshing which makes it easy to make changes and quickly view them on the live site too.

On leaving Kirby etc.

For a few weeks now my wife has been asking me why I have been playing around with my website design so much. She was not alone: eight readers contacted me over the past month enquiring about the same thing. The answer is everything above. All that I said for Physics Capsule applies for this website too. You are reading this article right now on a static site built with Hugo, hosted on a Git repo and served by Netlify.

The reason I made this move was two-fold: first, unlike before, my work was demanding enough time that I could not dedicate a few hours every month towards maintaining the site, whether for security or for functionality or for design; second, during the past eleven years that this website has been functioning I have moved only once (from Wordpress to Kirby) and my previous set-up with Kirby 2 was great except that with the launch of Kirby 3 I had to purchase a new license to upgrade and that turned out to be nearly four times costlier than my Kirby 2 license—additionally, staying with Kirby 2 was not a future-proof option since, somewhat rudely I find, all Kirby 2 docs were pulled and replaced with Kirby 3 docs. If I ever ran into an issue I would have no references or support except perhaps from the active community on Kirby.

Content lock-in can be a nightmare. In the interest of keeping things simple and future-proof I did not want to compromise on using pure Markdown for writing articles.

The community on Hugo is just as active if not more so. Building sites while different1 shared several core beliefs that made it easy to design this from scratch. The many designs I had been exploring the last couple of months before this helped me finally arrive at my current design. I realised that I wanted a mature set-up that could take fairly good care of itself without my constant attention, and one on which wiritng was as easy as writing any longform content today on my computer. I also realised that my priorities with respect to design and function too had changed.

For starters, any design had to be functional and minimal. I have always rooted for something minimal but this time round, embracing the JAMStack, I wanted my code to be minimal as well: fetch few external assets, fetch nothing unnecessary, defer and async as needed, focus on speed and simplicity. At the top of my list, for functionality, was a dark mode. You can click the adjustment icon in the menu above to switch between a bright (daytime) and dark (nighttime) mode. These have been carefully designed to look as beautiful as possible. Coupled with Minion2 and Bernina Sans, the rich palette and sprinkles of javascript magic make this website something I can be happy about, something that is simple and straightforward and easy to manage; something that lets me truly focus on my content while making pushing commits laughably easy.

Speaking of content, a sad lesson I learnt with Wordpress and Kirby is that content lock-in can be a nightmare. Sure, Wordpress exports files but it does so in a human-unreadable .xml format. Kirby does some exporting in that its content files can simply be copied elsewhere but it relies on proprietary Kirbytags for a lot of functionality. It does have a panel (via a browser) and a CLI but the latter, as of the time of writing this article, is lagging behind with no support in Kirby 33. Therefore, simple copy–pasting to export Kirby articles does not always do. In the interest of keeping things (once again) simple and future-proof I did not want to compromise on using pure Markdown for writing articles. Wordpress too came up with a solution for this in Gutenberg but the editor feels rather half-baked to me right now, even in Wordpress 5.0+. Plus, Markdown is not a standard Wordpress feature; you need Jetpack for that.

Hugo on the other hand supports Markdown in conjunction with the Blackfriday Markdown parser for Go. No extra set-up is needed, not even a coulpe of lines in the config.yaml file like Kirby’s config.php and Markdown Extra. Hugo even supports footnotes out of the box, as you may have noticed on this page, and these are standard Markdown Extra syntax footnotes, not custom shortcodes. That said, Hugo does support building some standard shortcodes and custom shortcodes; it is simply that I would rather not use them. All-in-all, what Hugo offers is a means of keeping my writing ‘rich’ without content lock-in, made possible by robust markdown support. It did mean I had to give up some fancier stuff in that I now have to type a div section manually rather than with fancy buttons like in Wordpress but this is a small price to pay for pull quotes that I use rarely.

There is something blissful about such a set-up as this, not the least of which is the knowledge that it is rock-solid (unlike Wordpress4), and that it is simple, easy to use, straightforward, future-proof with fairly good backwards compatibility (unlike Kirby). That is not to say that either Wordpress and Kirby are bad: I enjoyed my Kirby site while it lasted, and I see that Wordpress has its perks when building sites for clients. Neither are for me—at least not right now.

The simplicity afforded by Hugo, the speed of my workflow, the ease of setting things up, the security offered, the robust asset pipeline, the absence of any form of lock-in, and the convenience of managing my website on a daily basis all made this move to Hugo reasonable for me despite minor additional tasks along the way, like transferring select data over. If you think I am the only one jumping platforms, think again: Eric Bernhardsson has a nice little contingency plot that shows just how common this practise is today. And guess what that plot says: Go is, in all likelihood, the future of programming such stuff as static sites. Wonderful.


  1. Kirby uses the latest version of the old horse php whereas Hugo uses the more modern Go. [return]
  2. Minion is downright my favourite typeface of all time—even my wedding invitations and envelopes were typeset in Minion when I designed them last year. [return]
  3. Kirby argues that working on the CLI takes away focus from the CMS itself. Hugo, on the other hand, embraces the command line beautifully. Perhaps these are two separate, equally valid routes; it is just that I prefer the latter. [return]
  4. On Wordpress any plugin could break your entire website and you would not even have a method of identifying the culprit easily. [return]