Jul 22, 2016

Redefining the BBC News core experience

In the beginning of 2012 the BBC Responsive News team wrote about how they provide a “core experience” for users by default, and then progressively enhance the page if the browser cuts the mustard. At the time, this was cutting edge. They were able to build pages that worked on practically any browser without compromising the experience for users on modern browsers. To quote directly from the Responsive News blog:

This technique is still in use today, and is an integral part of the front-end strategy for all modern BBC News pages. In 2012 it allowed the team to provide a fast and lightweight experience for users on low-end devices. 7 HTTP requests totalling 21KB was all it took to load the core experience of the BBC News front page. All users benefited from this fast initial page load, with modern browsers progressively enhancing the rest of the page after the content was loaded.

It has been over 4 years since the BBC News core experience was first built, and a lot has changed since then. Today, the core experience consists of 91 HTTP requests totalling 685KB – over 32x heavier than the original core experience. With JavaScript disabled this can be reduced to 137KB – still over 6x heavier.

The BBC News team is aware of their website’s shortcomings. Back in May 2015 I conducted a huge performance review which I’ve spoken about extensively both internally and externally (video). A lot of work has been done over the last year, and many of the issues mentioned in those slides have already been addressed. Despite this, the elephant in the room is still the core experience.

That’s why when BBC News ran an internal hack day (where people can form teams to work on whatever they like) I took the opportunity to totally redefine the BBC News core experience.

(Read more)
Mar 28, 2016

How can we fix open source culture?

The recent kerfuffle around the NPM #unpublishgate and the Greenkeeper bot impersonation has got me thinking about the open source community and its culture.

Sometimes the open source community feels like a wonderful, cooperative, welcoming place. There have been times when maintaining an open source project has given me an enormous sense of satisfaction and well-being. On the best days, complete strangers offer valuable feedback and even actively contribute to my projects.

On the worst days I feel drained, unappreciated, and even abused. Stephan describes this more concisely than I could right at the bottom of Your “just” considered harmful:

This is the part of the open source culture that we need to fix. Entitled and toxic are not words that I associate with welcoming and inclusive communities. Yet they are completely apt descriptions of behaviour which is common within the open source community.

I don’t have any solutions to offer. I’m merely venting some frustrations which have been building up for quite some time. But we need to fix this. I don’t want to see this toxic behaviour cause another friend, colleague, or community member to suffer.

How can we fix open source culture?

(Read more)
Aug 23, 2015

Accidental Keyboard Enthusiasm

Over the last 5 years I’ve managed to collect quite a few mechanical keyboards, to the point where I think I qualify as an (accidental) enthusiast.

Das Keyboard (3) Model S Ultimate

This was my first mechanical keyboard. The soft Cherry MX Brown switches make it my favourites for long periods of typing. Even so, I rarely use it any more. At the time of writing, this model is still available on the Das Keyboard website.

Das Keyboard Model S Ultimate

CODE Keyboard

I was really excited when Jeff Atwood announced the CODE keyboard. I already knew that I wanted my next keyboard to be compact and have backlit keys, so the CODE seemed to come at just the right time. Not long after buying the CODE, I purchased some Keycool rainbow keycaps so brighten things up.

The CODE has Cherry MX Clear switches, which makes for a much firmer keyboard than the Das. I find the clears preferable for short bursts of typing, but over long periods they tire my hands out.

CODE keyboard with Keycool rainbow keycaps


As I’ve mentioned in a previous post, I decided that I wanted a split-hand keyboard. After much searching, I settled on buying an ErgoDox kit from Massdrop. This was a really fun project and involved spending plenty of time at the London Hackspace soldering station. The ErgoDox is by far the most comfortable keyboard I’ve used – I like it so much I’ve even placed an order for the next generation ErgoDox.

My ErgoDox has Cherry MX Clear switches. Somehow the clears on the ErgoDox feel much softer than on the CODE, so I’m able to enjoy the feeling of firm keys without the fatigue I experience with the CODE.

ErgoDox keyboard
(Read more)
Jul 27, 2015

Functional Programming Resources

This post contains a collection of resources for learning about functional programming. These resources cover a range of levels from beginner-friendly introductions right through to more advanced concepts. (Read more)

Jul 8, 2015

Some Git Things

Some notes on terminology

In case you’re not familiar with some of the terminology used below, here is a small glossary.


An object in Git is either a blob (file), tree (directory), commit, or tag. All objects in Git have a hash (like 99b69df491c0bcf5262a967313fad8be0098352e) and are connected in a way that allows them to be modelled as a directed acyclic graph.


A reference in Git is a bit like a pointer, or a symlink. References are not objects themselves, and they always point to either an object or another reference. Branches, tags, and HEAD are examples of references.

You can learn about all of this and much more in my Hacker’s Guide to Git.

(Read more)
Apr 26, 2015

Cabal: Installing readline on OSX

I’ve had trouble installing the readline package on a few separate OSX installations, so I figured it was worth writing the solution down.

When running cabal install for a package which depends on readline (or simply when running cabal install readline), Cabal exits with errors along the lines of

Configuring readline-
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for GNUreadline.framework... checking for readline... no
checking for tputs in -lncurses... yes
checking for readline in -lreadline... yes
checking for rl_readline_version... yes
checking for rl_begin_undo_group... no
configure: error: readline not found, so this package cannot be built

The problem is that Cabal is not aware of the location of the readline lib. My workaround is to specify the location of the lib whenever running these commands:

$ cabal install readline --extra-include-dirs=/usr/local/Cellar/readline/6.3.8/include/ \
                         --extra-lib-dirs=/usr/local/Cellar/readline/6.3.8/lib/ \
                         --configure-option=--with-readline-includes=/usr/local/Cellar/readline/6.3.8/include/readline \

Your paths may differ slightly if you have a different version of readline installed. You can check this with

$ ls /usr/local/Cellar/readline
(Read more)
Oct 31, 2014

Transitioning to a new keyboard layout

I’ve long been considering switching to a different keyboard layout. I tend to type with mostly my forefinger and middle finger, only using my ring and pinky fingers occasionally to stretch out to the modifier keys. Despite this, I still manage to type at around 120WPM on a staggered QWERTY keyboard.

Thinking back, I probably started teaching myself to type at a reasonable speed around age 10. I’m now in my mid-twenties. My typing technique (or lack thereof) never really bothered me, but 15 years of typing with poor technique has started to take its toll. Recently I’ve started experiencing hand fatigue, and I’m beginning to see early signs of RSI. So I figure now is the perfect time to make some changes to the way I type.

(Read more)
Aug 2, 2014

JavaScript Performance: Variable Initialization

Initializing variables properly in JavaScript can have significant performance benefits. This can be shown with a simple synthetic benchmark.


var x = null;

for (var i = 0; i < 1e8; i++) {
    x = 1 + x;


var x = 0;

for (var i = 0; i < 1e8; i++) {
    x = 1 + x;
(Read more)
May 25, 2014

A Hacker's Guide to Git

A Hacker’s Guide to Git is now available as an e-book. You can purchase it on Leanpub.


Git is currently the most widely used version control system in the world, mostly thanks to GitHub. By that measure, I’d argue that it’s also the most misunderstood version control system in the world.

This statement probably doesn’t ring true straight away because on the surface, Git is pretty simple. It’s really easy to pick up if you’ve come from another VCS like Subversion or Mercurial. It’s even relatively easy to pick up if you’ve never used a VCS before. Everybody understands adding, committing, pushing and pulling; but this is about as far as Git’s simplicity goes. Past this point, Git is shrouded by fear, uncertainty and doubt.

(Read more)
May 9, 2014

Understanding JavaScript: Inheritance and the prototype chain

This is the first post in a series on JavaScript. In this post I’m going to explain how JavaScript’s prototype chain works, and how you can use it to achieve inheritance.

First, it’s important to understand that while JavaScript is an object-oriented language, it is prototype-based and does not implement a traditional class system. Keep in mind that when I mention a class in this post, I am simply referring to JavaScript objects and the prototype chain – more on this in a bit.

Almost everything in JavaScript is an object, which you can think of as sort of like associative arrays - objects contain named properties which can be accessed with obj.propName or obj['propName']. Each object has an internal property called prototype, which links to another object. The prototype object has a prototype object of its own, and so on – this is referred to as the prototype chain. If you follow an object’s prototype chain, you will eventually reach the core Object prototype whose prototype is null, signalling the end of the chain.

So what is the prototype chain used for? When you request a property which the object does not contain, JavaScript will look down the prototype chain until it either finds the requested property, or until it reaches the end of the chain. This behaviour is what allows us to create “classes”, and implement inheritance.

(Read more)
Mar 10, 2014

Defining readable code

Code readability is something that I often bring up during code reviews, but I often have trouble explaining why I find a piece of code to be easy or difficult to read.

When you ask programmers how to make code easier to read, many of them will mention things like coding standards, descriptive naming, and decomposition. These things actually aid in making code easier to comprehend rather than easier to read. For me, readability is at a lower level, somewhere between legibility and comprehension.

Legibility - Readability - Comprehension

At the lowest level is legibility. This is how easily individual characters can be distinguished from each other, and can usually be boiled down to the choice of font, as well as the foreground & background colours.

At the highest level is comprehension, which is the ease in which a block of code can be fully understood. Decomposition, naming conventions and comments are just a few of the many ways to improve comprehension.

Readability sits between these two. This level is a little harder to define, but I believe it comes down to two main factors: structure and line density.

(Read more)
Sep 30, 2013

HTTP status as a service

Using Node.js* you can run a simple “HTTP status as a service” server. This can be useful for quickly checking whether your application handles various status codes.

var http = require('http');

http.createServer(function (request, response) {
  var status = request.url.substr(1);

  if ( ! http.STATUS_CODES[status]) {
    status = '404';

  response.writeHead(status, { 'Content-Type': 'text/plain' });
}).listen(process.env.PORT || 5000);

This will create a server on port 5000, or any port that you specify in the PORT environment variable. It will respond to /{CODE} and return the HTTP status that corresponds to {CODE}. Here’s a couple of examples:

$ curl -i
HTTP/1.1 500 Internal Server Error
Content-Type: text/plain
Date: Mon, 30 Sep 2013 14:10:10 GMT
Connection: keep-alive
Transfer-Encoding: chunked

Internal Server Error%
$ curl -i
HTTP/1.1 404 Not Found
Content-Type: text/plain
Date: Mon, 30 Sep 2013 14:10:32 GMT
Connection: keep-alive
Transfer-Encoding: chunked

Not Found%

This is a really simple example, and could easily be extended to let you specify a Location header value for 30X responses.

(Read more)
Sep 6, 2013

Converting Bootswatch themes to SASS/SCSS

There’s a fairly quick way to convert Bootswatch themes to Sass (which you might want to do if you use something like sass-bootstrap).

Simply download the theme’s variables.less and run the following find/replace patterns against it:


Find (regex): @([a-zA-Z0-9_-]+)

Replace: \$$1


Find: spin(

Replace: adjust-hue(

This is all I’ve found in the themes that I’ve tried.

(Read more)
Aug 20, 2013

Getting Internet Sharing to work on OSX 10.8

I noticed that the Internet Sharing functionality didn’t work on my Macbook Air (running OSX 10.8 - Mountain Lion). This is because the Air’s DNS server (BIND) isn’t configured correctly.

For me, the fix was pretty simple. Edit /etc/com.apple.named.proxy.conf by running sudo nano /etc/com.apple.named.proxy.conf in a terminal, and change

forward first;


forward only;

Then turn Internet Sharing off and on again.

The annoying thing is that OSX seems to restore the BIND config the next time you turn Internet Sharing off, so you need to remember to change it each time.

(Read more)
Aug 16, 2013

Force Bower to clone from https:// instead of git://

Most Bower packages will be fetched using a git:// URL, which connects on port 9418. This can be problematic if you’re behind a firewall which blocks this port.

You can get around this quite easily by telling Git to always use https:// instead of git://:

git config --global url.https://.insteadOf git://
(Read more)