TermTypo

Terminal-first multiplayer typing test — ranked 1v1 races, an ELO ladder and a global leaderboard, cross-play between the CLI and a companion web app.

Services
Product DesignEngineering
Industries
Dev ToolsRealtime
Tools
PythonTypeScriptWebSockets
Highlight
A terminal can be a ranked competitive arena.
Live
termtypo.vercel.app

A terminal can be a ranked competitive arena

Typing tests live in browsers. That is not a technical fact, it is a habit — and it excludes the people who type most, who are already in a terminal and are not going to leave it to race someone.

TermTypo is a terminal-first multiplayer typing test: ranked 1v1 matches, an ELO ladder, and a global leaderboard, played from a shell. The web version exists too, and the interesting part is that they play each other.

Cursor pinned, text flows
Every keystroke, coloured
Cross-play, one ladder
A scrolling line, a live keyboard, and an opponent somewhere else.

Cross-play is the design decision everything else follows from

A terminal player and a browser player race each other, share a leaderboard and share a match history. That single requirement decides the architecture: the match cannot live in either client, so it lives in Supabase, and both front-ends are views of the same rows.

The terminal interface is a scrolling single-line display — the cursor stays pinned at centre as the text flows past — with a live keyboard visualisation colouring each keystroke green or red. That is more work than a static paragraph and it is what makes the terminal version feel like the real one rather than the fallback.

Seven separate mode ratings, ±30 per result, a floor at zero, and seven tiers from Bronze to Master.

Modes
10 / 25 / 50 / 100 words10s / 30s / 60sSeven ELO ratings
Ranked
1v1 matchmakingCross-play CLI ↔ webShared leaderboard
Stack
Python 3.10+SupabaseGoogle OAuth on localhost:54321
Delivery
PyPI packagePlatform binariesWeb companion
Bronze to Master
Live WPM and elapsed
Disconnect: auto-win at 45s

01 / 03

What it cost

OAuth in a terminal is genuinely awkward. There is no browser to redirect and no address bar to read a token out of, so the CLI stands up a local callback server on localhost:54321, opens a browser, and catches the redirect itself. It works, and it is the part that surprises people who assume a terminal app cannot have real accounts.

Rating a game with seven modes is seven games. A single ELO across all of them would let someone farm the easiest mode; seven separate ratings is more state, more UI and the only version that means anything.

Where it does not work yet

Disconnection is handled by a timer — 45 seconds and the remaining player wins — which is the blunt version. It cannot tell a rage-quit from a train going into a tunnel, and it should eventually.

And distribution is the ongoing cost. A PyPI package and platform binaries are two release paths that have to stay in step with a schema that both of them and the web client share.