Touch typing for programmers: symbols, numbers and the speed that matters

Touch typing for programmers is mostly about the keys a normal typing course skips: digits, brackets, operators and the Shift combinations around them. A programmer who types prose at 90 WPM can be slow at code, and a 50 WPM prose typist can be quick at it. We noticed this while pasting our own source files into custom mode during testing. Speeds fell by a third or more compared with words mode, the per-key heatmap lit up on the number row and the right pinky, and the slowest bursts were on tokens with brackets in them.

Why prose WPM is a poor proxy for typing code

Code differs from text in three ways, and a typing test built from common English words measures none of them.

The first is the character mix. We counted. Across the first ten posts on this blog, about 93 of every 100 non-space characters are letters, 5 are punctuation and 2 are digits. In the JavaScript source of npm's command-line tool, letters fall to about 80 and symbols rise to 19. Python's json and email modules come out at 80 to 85 letters, and a dense build script of ours at 64, with a third of its characters symbols. So code has roughly three to seven times as many symbols as our prose. Most of them live on the top row or need Shift, which means the right pinky and the weaker reaches. Our English word tests are built from the 1,000 most common words in a subtitle corpus; "{" is not among them.

The second is rhythm. Prose is typed in long runs. Code is typed in short bursts between pauses for thinking, scrolling and reading. The volunteers in Dhakal et al.'s 2018 study of 136 million keystrokes, who were copying sentences, averaged about 239 ms between keys. A programmer's day is full of gaps lasting several seconds, and burst speed inside the short runs matters more than any average.

The third is the editor. Autocomplete, snippets and keyboard shortcuts mean a working programmer types a fraction of the characters on screen. No typing test can measure that, and ours doesn't pretend to.

Is typing speed important for programming?

Less than people think, and in a different place. When someone asks whether 60 WPM is enough to be a programmer, the answer is yes, with a caveat: if you look down for symbols and numbers, 60 WPM is not what you type code at. Being able to type a line without breaking your train of thought matters more than raw speed, and looking down at the keyboard is what breaks it.

How to type symbols faster, and why nobody teaches it

A question that comes up again and again on typing forums: someone can touch type letters at a decent speed, but the moment they start coding they're back to hunting for symbols, numbers and even capitals, and they want a gradual way to learn those, the way they learned the letters, a few keys at a time.

Part of what makes symbols hard is Shift. In the npm source we counted, about 45% of symbol keystrokes were shifted characters such as ( ) { } : and $, close to 9 in every 100 non-space characters before you count a single capital. So fix the Shift habit first: press Shift with the hand that isn't typing the character. ( and ) sit on the right hand's 9 and 0, so they take left Shift; ! @ # $ sit on the left hand, so they take right Shift. Most self-taught typists hold left Shift for everything, and for ! that asks the left pinky to press two keys at once. Check your own habit by typing a line with @ and $ in it and watching which pinky moves.

Symbols are hard to drill in isolation and dull to drill at all: letters come with words, brackets come with code, and random code is not interesting. Our answer is to drill symbols on real lines of code, one class at a time.

One class at a time

This is the order we'd use, and the order of the symbol track we're building for the practice page. Until it ships, you can do the same by pasting real code into custom mode, one class of symbols at a time, and not adding the next class until the current one is at 95% accuracy:

  • Digits. The number row, with the home-row fingers reaching up. This comes first because it's the most-used non-letter class and because nearly everyone has a bad habit here, such as the index finger doing 4, 5, 6 and 7. The numbers test is a quick check.
  • Brackets as pairs. ( ) first, then [ ], then { }. Pairs, because you almost never type one without the other: in that npm source, ( appears 6,195 times and ) 6,194. Training the open-close motion as one unit is what makes it fast. The closing bracket is where most people's rhythm breaks.
  • Operators. = + - * / and the angle brackets, plus the compound forms (==, =>, +=, !=). These are spread across the number row and the right-hand punctuation keys, and several need Shift on the same hand, which is the awkward part.
  • Quotes and punctuation. ' " ; : , . with the right pinky doing most of the work. Semicolons and colons are where C-family and Python typists differ most, so practice on lines from the language you use.
  • Shell and the odd ones. Pipe, backslash, tilde, backtick, caret, ampersand, hash, dollar, at-sign and the _ key. The _ and the backtick surprise most people; snake_case code uses _ constantly, and most typists hit it with the wrong finger.

Each class takes most people a week or two of ten-minute sessions, so the whole track is two to three months. That's slower than learning the letters, because the symbol keys are further away and the habits you're replacing are older.

What goes wrong, from watching the per-key stats: people learn the symbol with the correct finger and then revert under pressure, because the old movement is faster for a few weeks. The stats show it as a key whose interval varies wildly, fast when you reach correctly and slow when you don't. The fix is to stay on that class for another week.

Bracket pairs and auto-closing

Editors auto-close brackets, which raises a fair question: why learn to type the closing one?

Two reasons. Auto-closing is inconsistent: it fires in some places and not in others, such as a terminal or a chat window. A typist who relies on it hesitates every time to check whether it fired, and the hesitation costs more than the keystroke. And typing over an auto-closed bracket (pressing ")" when the editor already inserted one) is itself a keystroke, so you type the closing bracket either way.

When you paste code into custom mode here, the text is split on whitespace, so indentation disappears and each token becomes a word. That's a limitation and a convenience at once: you don't type four spaces at the start of every Python line, and you don't practice them either. A proper code mode that handles indentation and auto-closed pairs the way an editor does is on our list, and it's harder than it sounds.

Code versus prose speeds

We don't have enough code-mode results to publish percentiles, and we'd rather wait than invent them. In our own runs, code speed on a realistic snippet has been somewhere around half to two-thirds of the same person's prose speed, and the ratio improves more with symbol practice than with general practice.

The number that does transfer is accuracy. A programmer who types prose at 97% accuracy and code at 90% has a symbol problem, and the per-key heatmap shows exactly which symbols. A programmer at 97% on both just needs to type more code. Our scoring methodology explains how accuracy counts corrected mistakes.

For a standard benchmark, the punctuation test with numbers switched on is the closest of our regular modes to code. It won't have braces, but it brings in the Shift key and the number row, and for most people those are the gap.

Keyboard choices that help

The keyboard advice programmers get is mostly about switches, and mostly beside the point.

Layout matters more than switch. Dvorak moves the brackets up to the number row and relocates most punctuation. Colemak and Workman keep the brackets where QWERTY has them, but both move the semicolon to where QWERTY has P, which C-family programmers will feel. The layouts article has the long version.

A symbol layer beats a bigger keyboard. Many split and compact keyboards let you put brackets and operators under the home-row fingers on a layer held by a thumb key. Of all the hardware changes programmers describe, this is the one we'd try first, because it means you never look down for a symbol again.

ISO versus ANSI. On ISO keyboards (UK and most of Europe), the extra key beside left Shift and the tall Enter key change where backslash and pipe live. If you practice on one and work on the other, your pinky will miss. Our emulation ships both variants of Colemak-DH for that reason.

Switches barely matter for speed. Linear, tactile and clicky switches differ in feel and sound, and the keystroke log doesn't know which you pressed. Our mechanical keyboards article goes through the numbers.

Sound helps some people with feedback: the error sound tells you a symbol was wrong without looking down. Turn it on while learning symbols.

A ten-minute programmer's session

What we'd do daily for the two or three months the symbol track takes:

  • Two minutes: a 30-second words test as a warm-up, accuracy at 97%.
  • Six minutes: the current symbol class, on custom text pasted from your own code. Stop at the first sign of reverting to the old finger.
  • Two minutes: one code snippet in the language you use most. Look at the per-key heatmap afterwards, not the WPM.

On the days you don't have ten minutes, type the closing bracket yourself. It's the smallest habit in this article and usually the first to pay off.

Frequently asked questions

What is a good typing speed for programmers?

Anything from about 40 WPM up is workable if you touch type symbols and numbers. Past that, the bottleneck is thinking, reading and editor skill, not finger speed.

How do I learn to touch type numbers?

Practice the number row on its own until accuracy holds at 95%, using the finger directly below each digit on the home row, then mix numbers into normal text.

Sources