Porting a phone app to a browser extension
KeyRush started on iPhone and Android. When we decided to bring it to Chrome, we had a choice: wrap the existing app in some cross-platform layer, or rewrite it for the browser. We rewrote it, porting from the Android version. Plain JavaScript, Manifest V3, no framework and no build step. Here’s what we learned doing that.
The keyboard is real now
On a phone, a typing trainer is an approximation. The on-screen keyboard is the input device and the subject at the same time, which is a slightly strange situation. In the browser, the user has an actual keyboard under their fingers — the very thing the app is trying to teach.
That changed more than we expected. Layouts differ between countries and between machines. Modifier keys exist. People hold keys down, press two at once, switch layouts mid-session. On a physical keyboard every small inaccuracy in the trainer is felt immediately, so we had to be far more careful about what counts as a correct keystroke.
We kept the on-screen keyboard, but its job changed. On a phone it’s what you press. In the extension it’s a guide: it lights up the key you should press next, so you can keep your eyes on the screen instead of your hands. That’s the whole point of touch typing, and the browser let us take it seriously.
Window sizes are not a fixed set
Phone screens come in a handful of shapes. Browser windows come in any shape at all. An extension popup is narrow and short; a full tab can be enormous. The same app had to make sense in both.
So we offer both. KeyRush opens as a popup for a quick test, and in a full tab when you want room for lessons and races. Alt+Shift+K opens it without reaching for the mouse — which, for a typing app, felt like the right default.
Popups forget everything
A popup closes the moment you click outside it, and whatever it was holding in memory goes with it. On Android, an app can be backgrounded and come back exactly where it left off. In a popup, you have to assume the user may vanish at any moment.
So everything that matters lives in browser storage rather than in the window, and the popup and the full tab read from the same stored state. Finish a test in the popup, open the full tab, and the result is already there. It’s a small architectural decision that made the whole extension feel more solid.
Permissions are a design decision
Android apps declare permissions too, but users rarely read them. Extension users often do, and the browser puts the warnings right in the install prompt. KeyRush asks for exactly one: storage. It doesn’t need to see the pages you visit, so it doesn’t ask. We wrote a separate post on why that matters to us.
What we kept
Almost all of the actual product came across unchanged: timed speed tests of 15, 30, 60 and 120 seconds, touch-typing lessons organised by finger, races against computer opponents, statistics, a heatmap of the keys you miss, the daily challenge and all 44 achievements. Someone moving from the phone to the extension should feel at home within a minute.
We also kept the principles. It works fully offline. Progress lives only in your browser. There’s no account and nothing to sign in to.
Why we didn’t share code
A rewrite sounds expensive, and in some ways it was. But a typing trainer isn’t a large app, and the logic that matters — scoring, lessons, levels, achievements — is small enough to port carefully by hand from the Android original. In exchange we got an extension that loads instantly, has no third-party dependencies to keep updated, and behaves like it was made for the browser, because it was.