Offline-first retail POS
The till a working shop rings up real sales on, built to keep going when the internet does not.
Context
The same retailer needed a point of sale for the shop floor. Off-the-shelf options assumed a stable connection and a monthly fee in foreign currency. Neither assumption survives contact with a shop in Accra.
The problem
- Network drops mid-sale. A cloud POS means a queue of customers and no way to take money.
- Card and mobile money already move through a separate bank terminal. The software had to record those payments without pretending to process them.
- The owner needed to see what sold, when, and by which payment method, without learning a new system.
- It had to feel like an app on a Windows machine, not a browser tab someone could close.
What I did
Local database, no network dependency
Prisma over SQLite on the shop machine. Every sale, item and receipt is written locally. The connection is irrelevant to whether the shop can trade.
Real receipts
Direct printing to a 58mm thermal printer, formatted for the paper width rather than shrunk down from an A4 layout. First time working with thermal hardware, and most of the work was in the format, not the driver.
Records payment, does not process it
Cash, card and mobile money are each recorded against the sale with a timestamp. The money itself moves on the bank terminal. Being honest about that boundary kept the system simple and the books accurate.
Admin view for the owner
A local admin panel breaking sales down by payment method and time, so the owner can reconcile a day without exporting anything.
Calls I made
Dropped Electron for a lightweight launcher
Electron's bundle and storage footprint were disproportionate to a till that does one job. A Windows launcher script opens it as a desktop app instead, with a fraction of the weight and nothing to update.
Offline-first rather than offline-tolerant
Sync-when-available designs still fail in the moment they are needed. Writing locally first means there is no degraded mode, because there is no online mode to degrade from.
Open sourced the repo
Other small retailers in the same market have the same problem and the same constraints.
Where it landed
- In daily production use, ringing up real sales on the shop floor.
- Works through network outages with no change in behaviour.
- Receipts print to thermal hardware on every sale.
- Owner reconciles the day from the local admin panel.
- Source is public on GitHub.
Open for work
Got something that has to work on a bad connection, in a real shop, with real money?
Open to full-time remote roles, freelance projects and collaborations. Tell me what you are building and I will tell you honestly whether I am the right person for it.