Touch typing that measures itself honestly.

A portable trainer and speed test. 62 position-based lessons, 9 keyboard layouts, seeded races you can share, and timing accurate to the keystroke. One container, no build step, no network, no account.

untyped correct wrong the colour of "correct" is yours to pick
two modes

Learn it, then prove it.

The app opens on two tabs. One teaches, one measures. Both share the same engine, so the numbers mean the same thing in each.

learn

A real curriculum

62 lessons across 9 units: home row, top row, bottom row, shift, punctuation, digits, symbols, fluency, and one called extra hard. Two new keys at a time, accuracy gated before speed.

test

Timed, counted, or quoted

15/30/60/120 seconds, 10 to 100 words, short to long quotes, or your own text. Punctuation and numbers optional. Every run is seeded.

stats

A profile that accumulates

Per-key error rates and latency build up across runs into a heatmap, feed the adaptive weak-key lesson, and drive your personal bests.

run it

One command.

The image is nginx plus a folder of static files. Nothing to compile, nothing to install, no runtime dependency.

# clone and start
git clone https://github.com/bhagesh-h/tt.git
cd tt
docker compose up -d

Then open localhost:8080. Change the port with TT_PORT=9000 docker compose up -d.

# without compose
docker build -t tt .
docker run --rm -p 8080:80 tt

No Docker? Every script is a plain classic script with relative paths, so app/index.html opens straight off disk. Some browsers refuse localStorage on file://; when that happens tt keeps your settings in memory for the session and says so in the settings window.

use it

Everything is one keystroke away.

Just start typing. The clock begins on your first key, not on a countdown. There is no start button and nothing to click before you begin.

keydoes
tabrestart the current text
escnew text, new seed unless you pinned one
enteron the results screen: next run
ron the results screen: repeat the same text
ctrl + kshow or hide the on-screen keyboard
ctrl + ,settings
ctrl + backspacedelete the whole word

Race someone on identical text

Every run has a seed. Leave the box empty for a fresh one each time, or type one to pin it. copy challenge on the results screen gives you a link that reproduces the exact words:

https://bhagesh-h.github.io/tt/app/#m=time&v=30&s=k7q2mp&l=english1k&p=0&n=0

Anyone opening it types the same words in the same order. Test recipes deliberately exclude the keyboard layout, so a QWERTY player and a Colemak player race exactly the same text.

the curriculum

Written in key positions, not letters.

Lessons name a physical key, never a character. That one decision means the whole course works on every layout without a second tree, and the finger being trained is the same in every column below.

lessonQWERTYDvorakColemakQWERTZ
index anchorsf ju ht nf j
ring fingerss lo nr is l
middle fingersd ke ts ed k
19 drill generators home rowtop rowbottom row shiftpunctuationdigits symbolsfluency
scoring

Speed alone is a bad number.

Typing fast at 88% accuracy is not a skill worth rewarding. Someone still has to re-read and fix the text. So accuracy is cubed, and the score is built on top of that.

effective wpm = wpm × accuracy³ × (0.9 + 0.1 × consistency)
tt score      = effective wpm × text difficulty × 10
accuracymultiplier100 wpm becomes
100%1.000100
98%0.94194
95%0.85786
90%0.72973
85%0.61461
Runs under 10 seconds, under 30 keystrokes, or with idle gaps are recorded but never set a personal best. A 4-second burst can show 180 wpm and mean nothing. Full derivation →
timing

The part that is easy to get quietly wrong.

Every reported number comes from one artefact: the keystroke log. Nothing is sampled live, so nothing depends on frame rate or on how busy the browser was.

look

Pastel, and entirely yours.

Six themes, red green and blue in dark and light, plus one you build yourself. The keyboard stays a plain monochrome layout display with shallow 3D keycaps, so it never competes with the text above it.

9 layouts QWERTY USQWERTY UKQWERTZ AZERTYDvorakColemak Colemak-DHWorkmanNorman

Practising a new layout? Turn on remap input and tt reads the physical key you pressed and translates it through the layout you picked, so there is no need to change your operating system's keyboard settings.