dan@dlk25:~$ cat ~/projects/touchtype.md

touchtype

A touch typing trainer that looks like a terminal and measures where your time actually goes.

2026 · live · next.js, typescript, postgres, drizzle

Time, word-count and quote tests with live stats, a vim-style command line, an on-screen keyboard, eight CRT themes and a global leaderboard. Start typing to begin, tab restarts, : opens the command line.

Practice, not just a score

Practice beats repetition only when it is aimed, so touchtype times every keystroke and builds drills from what it finds.

  • Slowest key pairs. The interval between each pair of characters is recorded and ranked against your own median, and :drill builds a test out of real words dense in the pairs that slow you down.
  • Preview span. :preview 8 fades out everything past eight characters. Reading ahead is most of an expert's advantage, and narrowing it trains it.
  • Pacer. A ghost caret runs just above your rolling median. A plateau breaks when you push past comfort.
  • Mistakes by kind. A transposition is a timing problem, a neighbouring-key slip is a placement problem. Results name which one it was.
  • Your actual keyboard. The on-screen board is worked out from the browser and from your own presses, so a norwegian, german or french layout draws itself correctly.

The headline figure is a rolling median rather than a personal best, because a best rewards restarting until a lucky run lands.

The text never moves

A word renders its target and nothing else, so its width cannot change with what you type. Characters typed past the end of a word show as a bar growing from its end instead of new letters, because text that re-wraps while you are reading it makes a typing test unusable.

The numbers are not the client's

A leaderboard run carries a signed ticket and a keystroke log, and nothing else: there is no field in it that could hold a wpm. The server regenerates the exact words from the ticket's seed, replays the presses through the same code the browser uses and reads the speed off the result. Sign-in is an emailed code, and the database holds hashes, never the secrets.

← back to the terminal (q)