TypeTimer

How TypeTimer measures typing speed

By Mark Fulton · Last verified

TypeTimer scores a test in your browser from the characters you typed and the clock. The headline number is net WPM: gross speed (every character typed, divided by five, per minute) minus one word per minute for each uncorrected error still on screen when time ends. This page documents what the code actually does, including the parts that are less flattering. The worked examples below were produced by running the real scoring functions, not by hand.

The text you type

The default text is original prose, shuffled from a bank of passages and split into words. "Words" mode draws random common words, optionally with punctuation and numbers, and the 10 key page uses numeric groups. Fresh text is appended whenever fewer than 30 words remain ahead of you, so a fast typist never runs out before the clock does.

When the timer starts and stops

  • Start: the first input event that leaves text in the field. There is no start button. The clock is Date.now() at that moment.
  • Stop (timed tests): a 100 millisecond timer checks the clock and ends the test once elapsed time reaches the chosen length: 30 seconds, 1, 3, 5 or 10 minutes. The scored time is the elapsed time capped at the test length, with a floor of one second.
  • Stop (stopwatch and custom text): you end it with Esc or the Finish button, or, in custom text mode, by typing the last word.

Pasting into the typing field is blocked. Leading and doubled spaces, Enter and Tab are ignored, and a word can run at most 12 characters past the target before extra keystrokes are discarded.

Gross WPM

gross = (characters typed / 5) / (seconds / 60)

"Characters typed" is the length of the final typed stream at the moment the test ends: letters, punctuation and spaces, correct or not. Characters you typed and then backspaced are gone from that stream, so they do not add to gross speed. The divisor of five is the standard word length used across typing tests; see how WPM is calculated for why.

Net WPM (the headline number)

net = max(0, gross - uncorrected errors / (seconds / 60))

Uncorrected errors are counted in characters, from three buckets compared against the target text at the end of the test:

  • Incorrect: a typed character that differs from the target character in that position.
  • Extra: characters typed beyond the length of the target word.
  • Missed: target characters never typed in a word you have already moved past with the spacebar. The word you are still typing when time runs out is not charged for characters you had not reached yet.

Each such character costs one word per minute, spread over the test length (so a single wrong character costs less on a longer test). The result is rounded to a whole number for display.

Accuracy

accuracy = correct keystrokes / (correct + incorrect keystrokes)

Accuracy is counted per keystroke as you type, so it is stricter than net WPM: a mistake you fix with backspace does not hurt your net speed, but it does stay in your accuracy, because the wrong key was still pressed. A space pressed at the end of a wrong word counts as one incorrect keystroke. Backspace itself is not counted either way. Accuracy is shown to one decimal place, and is 100 when no keys were counted.

Other numbers on the results screen

  • Consistency: 100 minus the coefficient of variation of your per-second typing bursts, clamped to 0 to 100. It is a heuristic of our own, not an industry standard, and it shows 100 when there are fewer than three one-second samples.
  • Characters per minute: correct characters plus the spaces that ended a fully correct word, per minute.
  • Keystrokes per hour (KPH): gross characters typed per hour. Data entry postings quote it, and it is the same basis as gross WPM. See the KPH test.

Worked examples

Each row comes from running the engine's real scoring functions (computeCharStats, grossWpm, netWpm) over a scripted sequence of keystrokes, with the per-keystroke accuracy rules replayed in a script, because that part lives inside the typing component. The script is apps/typetimer/scripts/methodology-examples.mts in the repository.

RunLengthChars typedUncorrected errorsGrossNet (headline)Accuracy
A. 50 words, clean60 s30006060100%
B. Same, 3 slips fixed with backspace60 s3000606099%
C. Same, 1 wrong + 1 extra + 1 skipped character left in60 s3003605798.3%
D. 150 words, 1 wrong + 2 extra characters left in5 min9023363599.4%

Run B shows the difference between the two measures: three mistakes were corrected, so net speed is untouched (60), but three incorrect keystrokes were pressed out of 303, so accuracy is 99.0%. Run C shows the net penalty: gross is 60.0 and the three leftover characters take off 3 per minute, giving a net of 57. In run D the unrounded values are 36.08 gross and 35.48 net: three characters over five minutes cost only 0.6 WPM, which is why a long test forgives a stray error more than a short one.

Certificates and verification

Anyone can take the certificate test for free. A verified certificate is $4.99, one-time, and is only offered for standard timed tests of 30 seconds, 1, 3, 5 or 10 minutes. What happens next:

  1. The score is computed in your browser exactly as above and held locally while you pay through Stripe.
  2. After payment, the claim step sends the score to our server. The server checks it is plausible (net WPM a whole number from 0 to 400, accuracy and consistency from 0 to 100, a duration from the allowed list, a valid test date) and, where the Stripe secret key is configured, that the checkout session was actually paid.
  3. One certificate is issued per checkout session. It gets a random ID in the format TT-XXXXX-XXXXX, built from an alphabet that leaves out look-alike characters (0/O, 1/I/L), and the name, score, test length, test date and issue date are stored against it.
  4. Anyone can paste that ID into the verify page to see the stored record. If the certificate in your hand shows different numbers, it has been altered.

The Recruiter Pack works the same way with one difference: candidates take a fixed 3 minute test from a private link, and each submission spends one credit and issues a certificate into the same verify registry.

Known limits

A typing test run in a browser you do not control can only be so strong. In plain terms:

  • It does not prove who was typing. Verification proves a certificate is genuine and unedited. It does not prove who was at the keyboard. For high-stakes hiring, retest in person.
  • The server cannot recompute your score. We store totals, not keystroke logs or replays. The server checks ranges and payment, not whether the numbers match a real run, so a person who forges the claim request by hand could submit a score they did not type. We do not currently detect that.
  • Scripted typing is not detected. Paste is blocked, but there is no check for automated or injected key events, and no keystroke-rhythm analysis.
  • Timing runs on your device clock. The stop check fires every 100 milliseconds, and a busy or background tab can delay it. Time is capped at the test length, but characters typed in that gap still count toward gross speed, so a delayed stop can flatter a score slightly.
  • Short tests flatter you. A 1 minute sprint reads higher than a 5 minute run for most people. The 10-minute test is the better stamina measure.
  • Different text, different score. Passages are shuffled, and difficulty varies a little between them. Expect a few WPM of spread between runs, and read why every site reports a different WPM.
  • Shared score links are self-reported. A link made from the share button carries the numbers in its address, and anyone can edit an address by hand. Only a certificate ID checked on the verify page is a stored record.
  • Consistency is our own heuristic, not a standard metric, so do not compare it with other sites.

Try the tests

Each duration has its own page: the 1 minute, 3 minute, 5 minute and 10 minute tests, plus the WPM test (common words) and the accuracy test. All of them use the scoring described here.

Changelog

  • : Published this page. It documents the scoring as implemented on that date; no scoring behaviour changed with it.

Corrections

If anything here does not match what you see on a results screen, email Mark@Reinventing.AI and we will fix the page or the code.