The JavaScript Keyboard

Halil Coban
HackerNoon.com
8 min readMay 7, 2019

--

TL;DR I played around with characters found in React codebase to design a keyboard layout based on character frequencies. The result is the above image.

Motivation

We developers tend to spend most of our time in front of laptops pressing keyboard buttons. Some of us, if not most, type very fast and think that this improves our productivity.

The most popular keyboard layout is the QWERTY layout which has some disadvantages when it comes to typing speed. It was specifically designed to prevent jamming of keys in old mechanical typewriters and by-design have speed-wise limitations. In addition, it doesn’t take into account that programmers (may) use some symbols more often than letters.

I decided to prepare a layout for a common programming language (JavaScript) based on very simple three principles.

  • Put mostly used keys in the home row (the row starting with ASD in QWERTY) and the least frequently used keys in the lower row
  • Balance load between left and right hands
  • Order load to fingers from the highest to the lowest as index finger, middle finger, ring finger, and pinky finger.

Analysis

I started with cloning a popular JavaScript repository, React, to my laptop. React is a JavaScript library for building user interfaces and as of now it has over 128,000 stars at GitHub. I targeted only files with .js extension.

The above python script simply traverses within the react folder and appends the files to an array to be used later. After executing, it output “Found 869 files”. I could then start making analysis within those files.

In order to achieve the principles I mentioned above we only need to calculate frequencies of characters.

frequencies is a dictionary mapping characters to number of appearances in the React codebase. It looks like

I decided to only focus on the most frequent 33 characters simply because there are 33 keys on my keyboard if you ignore F-row, number row, space-bar row, and the keys on the far-right and far-left where caps lock, return, etc keys are located. You can see below the keys I focused numbered from 1 to 33.

From the most frequent characters I filtered out \n and which corresponds to enter (return) and space keys, respectively, simply because they are often not located within the 33 keys on a regular keyboard.

According to our third principle we would like to give load to fingers in an order (from the highest load to the lowest load) index finger, middle finger, ring finger, and pinky finger. Due to the position of hands, usually left hand controls 5 keys in each row where right hand controls 5 keys in addition to a few extra keys controlled by pinky finger. Ignoring those extra keys I decided to focus on the 10 keys on each row. For a set of 10 keys each hand will be responsible for 5 keys, from which 2 of them will be pressed by index finger and the rest will be pressed by one of the other fingers (middle, ring, or pinky).

My algorithm for solving this is as follows

  • in each row distribute keys according to frequencies in an order
  1. index finger
  2. middle finger
  3. ring finger
  4. pinky finger
  5. again index finger (since index finger should take 2 keys)
  • in order to distribute the load evenly between two hands (principle 2) give one key to the left hand and one key to the right hand consecutively.

Consider the positions (indexes) of keys in a row from 0 to 9. The below table illustrates which index corresponds to which finger, for example key at index 2 (for example E in QWERTY) will be pressed by left middle finger.

Applying our algorithm above should produce a result as follows

  • The most frequently used key should be pressed by an index finger, let’s start with left hand so it will be left index finger (3). After that we should switch hand and use the right index finger (6)
  • Afterwards comes left middle finger (2) and right middle finger (7)
  • Afterwards comes left ring finger (1) and right ring finger (8)
  • Afterwards comes left pinky finger (0) and right pinky finger (9)
  • Afterwards comes again the left index finger (4) and right index finger (5)

making our frequency order to be 3, 6, 2, 7, 1, 8, 0, 9, 4, 5. We will use it later.

This ordering should take care of our 2nd and 3rd principles. In order to achieve the first principle we can simply start assigning most frequent keys to the home row, and the rest to the upper and lower rows.

We previously defined a dictionary frequencies mapping each character to number of its occurrences. Python dictionary is an implementation of hash map data structure which is great for fast look-ups, however, they are not sortable. We can define a list of characters using the frequencies dictionary and sort it by number of occurrences. Each element in this list can be a tuple of (character, frequency) so we can have access to both these values.

Now that we have frequent_chars we can loop through it to prepare a keyboard dictionary.

The result

If we print our keyboard dictionary it looks like this

which means that lower row, key at index 0 (the key to be pressed with left pinky, see the table above) will be } character and has 42020 occurrences in the JavaScript files in React codebase. The key just next to it should be g key with 45226 occurrences, an so on.

Since the script above handled 30 keys (10 keys in each row) but we actually have 33 frequent characters I decided to handle manually the least frequent 3 keys: x, w, and :. They were just assigned to the extra keys to be controlled by right pinky finger.

Let’s now visualise the layout and also include the usage percentages (occurrence of the key / total occurrence of all 33 most frequent keys) just below the characters.

On a first look at above layout, you’ll see that j, k, q, z, [, and ] does not exist within the most frequent 33 characters unlike regular keyboards. They are replaced by (, ), =,{, }, and :.

Each colour on the visual represents a separate finger in an order from left to right: left pinky, left ring, left middle, left index, right index, right middle, right ring, right pinky. As you can see most of the load was given to index fingers in the home row. But let’s take a deeper look.

64.22%, 24.35%, and 11.42% of character occurrences are handled by keys in the home row, upper row, and lower row, respectively. This is good and satisfying our first principle.

Let’s also check frequency percentages corresponding to each key and hand to better understand whether we achieved or not the remaining two principles.

Character frequency percentages of keys assigned to different fingers

Our second principle, balancing the load to left and right hand seems somewhat achieved, but definitely could be better. The load to the left hand (52.29%) is slightly higher than the one to the right hand (47.70). This is probably because we started assigning keys to the left hand first and alternated with each assignment. Actually, it would be better if we started with right hand because more load in the right hand is suitable for more people as 70–95% of the people are right-handed. In addition our very simple algorithm simply put one key to each hand consecutively which should be improved by for example taking into account the percentages, not only the order of them.

Our last principle was to have the most load on index fingers, and the lowest in pinky fingers with middle and ring fingers in between. We can see that this is mostly achieved, except for the right pinky finger. This was caused by assigning the additional fingers to the right pinky. We could have considered this when filling the keyboard dictionary with 30 keys.

Conclusion & Outlook

  • JavaScript developers use some characters like parentheses and curly brackets more than some letters like k and q
  • A simple algorithm can be used to balance keys to the hands equally and increase usages of home row and index fingers, but improvements are necessary
  • It would also be great to analyse which keys are frequently pressed after which (for example after i maybe f comes often to make an if) and take this into account when designing keyboard layout
  • Having a different layout for each programming language is not logical but a similar approach can be used to design a keyboard for general programming use by analysing most common programming languages

--

--