Articles
August 2026

The Link Is the Database

Handing the poker ledger from one phone to another, mid-game, with the whole table packed into a link.

The podium card: Tom up $72, Brian up $59, Michael up $31

I was the banker at our last poker night, and it wasn't going well. I was tired, and I felt like going home. The problem was that the whole game was on my phone, so if I left they wouldn't be able to cash up. I needed a way to hand the game off to Sam, and it turned out to need no backend at all.

The Poker Night Ledger tracks buy-ins, rebuys and chip counts for a whole table and settles everyone up at the end. It works well, and this was the one flaw that only showed up once I used it for real. Every number for the evening lived in my phone, which meant I was the ledger.

The Obvious Answer, and Why I Skipped It

The obvious answer is accounts and a shared session. Put the table in a database, let several phones watch it live, let anyone update it. That is a genuine feature, and it is also a Supabase project, a table, row-level security, realtime subscriptions, and a proper story for what happens when two people edit the same player at once.

It also wasn't what I wanted. I had no interest in watching the game from home. I wanted to hand it over and leave. That is a baton pass, not a sync, and a baton pass needs nothing more than a way to move the table from one phone to another.

Putting the Whole Table in a Link

So the entire table travels inside the URL: the stakes, every player, their rebuys, and any chip counts already entered. It is packed into a compact positional array rather than readable JSON, which roughly halves it, and a five-player game comes out at around 155 characters. That fits comfortably in a text message.

Two decisions did more work than the rest. The first is that the payload rides in the hash fragment, the part of a URL after the #, rather than in the query string. Fragments are never sent to the server. The player names never reach my host, never appear in an access log, and never sit in anybody's analytics. For a feature whose entire payload is a list of people's names, that isn't a small optimisation. It is the difference between handling personal data and not handling any.

The second is that opening the link doesn't do anything on its own. Sam gets a confirmation screen showing who is seated and what is in the pot, plus a warning if there is already a game running on that phone, and nothing is written until they tap "Take over as banker". A link that silently replaced your evening's bookkeeping would be a bad link.

Being Honest About What It Isn't

It is a snapshot, not a sync. Once the link is sent and accepted, Sam's phone is the ledger. If I add a rebuy to my copy afterwards, it goes nowhere.

Rather than quietly hoping nobody notices, the app says so. As soon as you hand off, your copy shows a banner explaining that their phone is the live ledger now, not this one. Two ledgers for one table is how poker night ends in an argument.

The Graphic I Couldn't Text

The second thing I wanted was to send whoever won the most money a congratulations graphic. This turned out to be flatly impossible in the form I imagined it.

A web page cannot attach an image to a text message. The sms: scheme carries a recipient and a line of body text, and that is the entire feature. There is no parameter for a file, and no amount of wanting one produces it.

What does work is drawing the card on a canvas, handing it to the phone's native share sheet as a file, and letting the sender pick Messages themselves. That has a pleasant side effect. Because the sharing happens inside the share sheet, the app never asks for anybody's phone number, never stores one, and never needs access to your contacts. The constraint made the privacy story better than the version I originally had in mind.

One thing did need fixing. The first version exported a PNG, and the felt-green gradient background pushed it to about a megabyte, comfortably over what plenty of carriers will accept as a picture message. The same card as a JPEG is 99KB.

The winner card: congratulations Tom, you were the big winner, up $72

Two Small Corrections

The card first read "you were the big winner tonight", above the exact figure, $72.12. Both were wrong in the same quiet way.

The cents belong on the cash-up table, where people are actually paying each other. On a graphic headed for a group chat they are just noise, so it rounds to $72. And "tonight" stops being true the moment you forget to send it until the morning, which is exactly the sort of thing I would do. It now says "You were the big winner", which is still true a week later.

The ledger still lives on one phone at a time. It just doesn't have to be mine.