Skip to content

An offline-first point-of-sale PWA in Cameroon

Published

On 2026-10-02 the Caisse Boutique account published a build report on dev.to, written in French, about a point-of-sale Progressive Web App made for small retailers in Cameroon. The post states that designing point-of-sale software for small shops in sub-Saharan Africa does not consist of copying Square or Shopify, and that three field realities have to be solved instead: the interruptions of the telecom networks it names as MTN and Orange, the high cost of mobile data megabytes, and cash handling. It introduces Caisse Boutique as an offline-first Progressive Web App designed for Cameroonian businesses, and says what follows is the architecture and the technical choices behind it (the report).

The conditions the report names, the architecture comparison it prints, the offline mechanisms it describes, the features it lists for the local market, and the merchant feedback it quotes are taken in turn below, in the wording the post itself uses.

The post describes the daily situation of a shopkeeper in Douala, naming a snack bar in Akwa, a grocery in Deido, and a hardware shop at the Marche Central, and describes the conditions below. The first is chronic connection instability: it states that 4G and 3G mobile networks are interrupted regularly during peak hours, and that if a point-of-sale program depends on a synchronous cloud API, the queue grows and the shopkeeper goes straight back to pen and notebook. The second is what it calls the friction of the Play Store: it states that asking a shopkeeper to download an 80 MB application from the Google Play Store consumes that person’s own internet bundle, and that many refuse or give up. The third is what it calls the invisible loss of money, which it attributes to unjustified cancellations of receipts by employees, approximate mental arithmetic, and undocumented stock theft (the report).

A figure is attached to the loss of money. The post states that on average a small business without a computerised till loses between 50,000 and 150,000 FCFA every month without noticing (the report).

The post gives its reason for choosing a Progressive Web App with what it calls a radical offline-first approach as a table comparing a native application distributed through the Play Store or as an APK against its own PWA. The rows, with the post’s own values, are download weight, 50 to 120 MB of mobile data for the native app against under 2 MB for the PWA; installation, a mandatory Google Play account against one click on “add to home screen”; network dependency, often blocked without a connection against what it calls fully autonomous offline operation using a service worker plus LocalStorage or IndexedDB; updates, heavy manual downloads against silent and instant updates on each reconnection; and compatibility, limited to recent Android versions against any smartphone, tablet, or old PC (the report).

The offline mode is described through named mechanisms. The first is cache-first handling of assets: the post states that the whole set of HTML components, Tailwind CSS styles, and application scripts is cached locally by the browser from the first opening. The second is local storage of transactions: every sale, stock change, or receipt print is recorded locally in what it calls a secure queue on the device. The third is background reconciliation: as soon as the device picks up the network again, over Wi-Fi or mobile data, a synchronisation engine pushes the transactions in batches to the central database without ever blocking the cashier’s checkout interface (the report).

MDN documents IndexedDB, one of the two storage mechanisms the architecture table names. MDN describes IndexedDB as a low-level API for client-side storage of significant amounts of structured data, including files and blobs, states that it uses indexes to enable high-performance searches of that data, and says that while Web Storage is useful for storing smaller amounts of data it is less useful for larger amounts of structured data. MDN also states that operations performed using IndexedDB are done asynchronously so as not to block applications, and that IndexedDB is available in web workers (MDN, IndexedDB API).

Bluetooth printing of 58 mm thermal receipts comes first, with the post stating that the paper receipt remains the absolute symbol of trust for the Cameroonian customer, that the application connects directly to the 58 mm mini thermal printers sold on local markets or on Jumia, and that the receipts automatically carry the legal mentions required by the DGI, which it lists as the NIU, the RCCM, and a sequential invoice number. Second is a WhatsApp receipt sent in one tap when no printer is at hand or the roll is empty. Third is a master PIN belonging to the owner, which the post says locks every sensitive operation, naming cancellation of a sale, an exceptional discount, and a change to the inventory. Fourth is the payment model: the post states that no international bank card is required and that the monthly subscription of 5,000 FCFA per month is payable directly through MTN Mobile Money or Orange Money (the report).

The post quotes feedback from a merchant it names as Papa Jean, who it says runs a neighbourhood grocery in Deido, Douala. The quotation given there, in French, is: “Avant, c’etait le cahier. Quand je devais m’absenter pour aller voir les grossistes, les produits disparaissaient et le compte du soir ne tombait jamais juste. Depuis que la tablette est posee au comptoir, je sais exactement ce qui a ete vendu, franc par franc, meme sans connexion. Les 5 000 FCFA d’abonnement me paient la paix du coeur.” It describes keeping a paper notebook before, stock disappearing and the evening count never balancing when the owner had to leave to see wholesalers, and knowing what has been sold since a tablet was placed on the counter, including without a connection (the report).

The post names a service worker as part of its fully autonomous offline operation, and MDN documents that mechanism. MDN describes service workers as proxy servers that sit between web applications, the browser, and the network when it is available, and states that they are intended, among other things, to enable the creation of effective offline experiences, to intercept network requests, and to take appropriate action based on whether the network is available. The same page states that service workers are only available in secure contexts, meaning the document is served over HTTPS, with browsers also treating http://localhost as a secure context to facilitate local development (MDN, Service Worker API).

MDN also documents constraints on that worker. MDN states that service workers run in a worker context, have no DOM access, and run on a different thread from the main JavaScript that powers the app, and that as a consequence APIs such as synchronous XHR and Web Storage cannot be used inside a service worker. MDN also states that service workers cannot import JavaScript modules dynamically, that import() throws an error when called in a service worker global scope, and that static imports using the import statement are allowed (MDN, Service Worker API).

The post’s receipt printing connects to thermal printers over Bluetooth, and MDN documents the Web Bluetooth API. MDN marks it as limited availability, stating that the feature is not Baseline because it does not work in some of the most widely-used browsers, and labels it experimental, advising that the browser compatibility table be checked carefully before production use. MDN describes the API as providing the ability to connect and interact with Bluetooth Low Energy peripherals, states that it can only be used in a secure context, and notes that it is not available in web workers because it is not exposed via WorkerNavigator (MDN, Web Bluetooth API).

  • Capabilities: the report’s receipt printer is a Web Bluetooth integration, and this page is where OpenPWA tracks the device and platform capabilities, Bluetooth among them, that a PWA can reach for.
  • Storage: the post’s offline queue is described as LocalStorage or IndexedDB on the device, and this page covers quotas, persistence, and eviction, which is what decides whether such a queue survives.
  • Performance: the post’s central comparison is a download-weight figure against a native app, and this page is where the performance budget side of that trade is documented.
  • Whether the figure of 50,000 to 150,000 FCFA lost per month by a small business without a computerised till rests on a study, a sample, or an estimate is not confirmed.
  • Whether the local transaction queue is written and read from the service worker or only from the page is not confirmed.
  • Whether the under-2 MB download figure covers the first load, the cached application, or both is not confirmed.
  • Whether the 58 mm thermal printers the post names work through Web Bluetooth on the specific browser and OS versions its merchants use is not confirmed.
  • Whether the merchant feedback quoted was gathered under any defined process, and whether more than one merchant was asked, is not confirmed.
  • Whether the post’s compatibility row, which it gives as any smartphone, tablet, or old PC, is meant to cover the Bluetooth receipt printing as well as the rest of the application is not confirmed.
  • Whether the application was tested on any of the widely-used browsers in which MDN states Web Bluetooth does not work is not confirmed.