1. Home
  2. /Work
  3. /Pharmacy POS

A till that keeps selling when the internet doesn't.

Till and stock software for shops in Ghana — a supermarket, a provision shop, a minimart, a pharmacy. Everything sits on the shop's own PC, so a dropped connection never stops a sale. Most shop software here is a website: when the link goes, the counter goes with it.

ElectronReact 19 TypeScriptSQLite · sql.js Offline-firstWindows
Talk to me about a counter system →

Project

Offline-first POS & stock control, Windows desktop

Field research

SMINAC Pharmacy, Accra — 24 Aug 2026

Status

Built & tested at their counter — not yet their live system

The wedge

It keeps selling when the internet doesn't

The interview that never happened

I went to SMINAC Pharmacy in Accra with a page of discovery questions. The owner did not want to answer them — "when the drugs come we just type it in." So I photographed his counter instead. Four photos. Every requirement below came off them.

They run LAVABMS in a Chrome app window. It is a website — no internet, no selling, and their data sits on somebody else's server. So the job was a till that keeps working when the link drops.

Expiry dates that say 2050

Some expiry dates on their screen read 01-Jan-2050 or 30-Apr-2039 — on the cannulas, the plasters and the multivitamins. The field is compulsory, so staff typed something to get past it. Those invented dates show up in the same green as stock that is genuinely fine.

This one will not show a made-up date in green. Products that never expire get a flag. Anything more than ten years out is pulled out of the expiry report and listed under "No real expiry date on file".

One product, three ways to sell it

Their product list has a Form column — Unit, Strip, Tab. Part-pack selling is normal here: somebody buys two tablets, not a box of two hundred. A normal till gives a product one price and one count, so a shop like this ends up with three products whose stock numbers drift apart. Here box, strip and tablet are one product sharing one pool of stock.

Search that survives their own catalogue

Real entries from their shelf list: PLASTES STRIPES, PENICILIN V TAB. 125MG 100'S, MULTIVITAMINE TABLETS. The typos are in the data, not just in what the cashier types, so search forgives both. A cashier who cannot find a product does not sell it.

Barcodes are the exception. A scan matches exactly or not at all, because a scanner makes no typos and a near miss is the wrong box in a customer's hand.

Offline by construction

The whole shop is one SQLite file on the counter PC. Stock is never stored as a single number. Every sale, delivery, return and write-off is its own row, and the count is those rows added up. A mistake is corrected by adding an opposite row, so nothing is ever quietly edited or deleted.

 the counter                   the internet
    │                                ✕
    ▼                          not needed
 Sell · Receive · Count        to sell
    │
    ▼
 append a stock_movement row (never edited)
   receipt +200 · sale −10 · write-off −6
    │
    ▼
 pharmacy.sqlite — one file, atomic save
    │
    ├─▶ stock = SUM(movements), not a column
    └─▶ backups\ daily, fourteen kept

It is not only for pharmacies

A pharmacy was the hardest first customer I could pick, which is why I picked it. Nothing in the build is medicine-specific — the same three problems turn up in most shops here.

Setting up a different kind of shop is a catalogue import and turning expiry tracking off if it is not wanted. It is the same software.

What came back from the counter

It went to the shop on my own laptop and was used by one person who sells there. Four faults came back, all four real, all four fixed.

What it is not

SMINAC has not switched to it. They are still running LAVABMS. It is not installed on their computer and it is not running the shop — it was taken to their shop on a laptop and used by one person who works there. No daily takings, no other shops, no testimonial. The Windows installer is not code-signed, so Windows warns on first run.

The real gap is a screen the owner can check from outside the shop. That one is not built yet.

Does your shop stop when the internet does?

Retail, pharmacy, spare parts, provisions — if your till is a website and the link is unreliable, that is fixable. Tell me how your counter works today. No price on this page; I haven't set one yet.

More work

Web app · Live

CoffieFX — membership platform

Mobile Money and crypto payments that unlock access automatically.

WhatsApp

Front Desk — an assistant on your number

Answers from your own prices, then hands the chat to a human.

Mobile app

SwiftDrop — delivery & errands

React Native, live map tracking, a full rider side with verified handover.