The buzzer worked everywhere. On my Mac, on my iPhone, on the test Android, across three browsers and two screen sizes. Then someone joined a game from a Galaxy A33, and nothing happened.
What I believed
The first instinct is always the wrong one. I looked at the network, because that is where real-time problems hide. Latency, dropped connections, a message that never arrives. I instrumented the server, added logs, checked timestamps. Everything was clean. The message was never sent, because the tap was never detected.
What it was
Samsung Internet handles the order of touch events differently from Chrome. The handler was attached through React’s event delegation, and the default behaviour was being cancelled before the actual call. On every other browser, the ordering hid the problem.
// before: depends on the browser's event order
onTouchStart={(e) => { e.preventDefault(); buzz(); }}
// after: the action first, the cancellation second
onPointerDown={(e) => { buzz(); e.preventDefault(); }}
Two lines. Three days.
What I take from it
AI tools write this handler correctly ninety-five percent of the time. The remaining five percent are not code errors: they are behavioural differences between browsers, which only show up on a device nobody on the team owns. No model will warn you, because the question only arises when a real user with a real phone presses a real button.
Build speed has been multiplied. The time spent checking that it actually works has not moved an inch.
That is, I think, the most important thing to understand about this period. You do not save time on quality. You save it on typing.
Get the journal by email
About one entry a week. What I build, what breaks, what I learn. No promotion, one-click unsubscribe.
You can also follow the RSS feed.