17 May 2026 · 7 min read
Below the dashboard — a 2026 technical audit of Indian pharmacy software
WPF in 2026, .mdb backups, fake Devanagari, AI bolted onto forms. A technical reading of what Indian pharmacy retail software is still made of, and the architecture the next generation requires.
The pharmacy software your local shop bought in 2024 is, technically, software from 2009. Not a metaphor. Open the install directory.
This post is an audit. It looks past the dashboards — the things vendors put on demo slides — at the layers underneath: the language runtime, the storage format, the text-shaping pipeline, the licensing surface, the deployment model. The category has been remarkably stable for fifteen years, and not in a good way. What follows is a reading of why.
§1 The stack archaeology
Take Marg ERP, the de-facto incumbent. Inspect a current install:
- The application binary is a WPF executable, compiled against .NET Framework 4.5+. WPF as a UI framework has been on Microsoft's "we'll still ship security patches but please stop building new things on it" list for the better part of a decade.
- Storage is MSSQL Server Express running as a local Windows service. The owner's actual transactional data — sales, purchases, stock movements, customer history — lives in
.mdfand.ldffiles inC:\ProgramData\Marg\on the back-room PC. - Multi-seat operation is done by pointing client machines on the LAN at the back-room instance over named pipes or TCP/IP on port 1433. The "server" is not a server. The "server" is the back-room PC.
- Updates ship via a ClickOnce manifest that the dealer's technician walks through over a phone call, or — for major version jumps — a fresh installer downloaded from a portal still using Internet Explorer–era certificate chains.
- Licensing is enforced by a hardware-fingerprinted activation code, often delivered on a printed card. Adding a workstation means a phone call to the dealer for a new code.
This isn't a critique of the engineers who built it — in 2009 this was a reasonable, even modern, stack. It's a critique of the fact that fifteen years later, nothing has been re-platformed. The .NET ecosystem moved to .NET 8. The storage tier moved to managed Postgres and SQLite-on-mobile. The deployment model moved to browsers, then to phones, then to edge. Indian pharmacy retail software stayed where it was.
§2 The data-locality problem
Because the database is local, every owner is operating their own data center without knowing it.
That means:
- Backups are a folder copy. "Take a backup" in the dealer's playbook is
xcopy C:\ProgramData\Marg\Data D:\Backup\Marg-{date}\. There is no incremental snapshot, no point-in-time recovery, no off-site replication. If the back-room PC dies, the books die. - There is no encryption at rest. MSSQL Express supports TDE only in the paid tier the shop isn't paying for. The
.mdfis plain blocks on an unencrypted NTFS volume on a Windows machine the owner's nephew has admin access to. - There is no audit trail you can trust in a dispute. SQL Server's Change Data Capture is also licensed out of Express. The application's own edit log can be
UPDATEd through Management Studio by anyone with the SA password — which is, statistically, "marg@123". - Recovery from physical loss is a story for an insurance claim, not a vendor. Theft, fire, ransomware encryption — the owner has no recourse against the software because the software was never the system of record. The PC was.
Every cloud SaaS pattern of the last decade — durable storage, point-in-time restore, encryption at rest, role-based access, off-site replication, tamper-evident logs — exists because we collectively decided this was an unacceptable failure mode. The pharmacy retail category never made that decision.
§3 Hindi as a font, not a language
A subtler but more revealing layer: how the incumbent stack handles Indic text.
Devanagari is a complex script. Rendering it correctly requires a shaping engine — HarfBuzz, Uniscribe, or CoreText — that walks the codepoint stream, identifies conjuncts (e.g. क + ् + ष → क्ष), applies vowel mark reordering (e.g. ि rendered before its base consonant), and selects the appropriate glyph variants from the font's OpenType GSUB tables.
The incumbent approach is none of that. The incumbent approach is:
SetFont(new Font("Mangal", 11)); // or DV-Surekha, or Krutidev
…and call it Hindi support. Some specifics of what breaks:
- Krutidev is not Unicode. It's a legacy 8-bit Devanagari font where each glyph occupies a Latin codepoint and the user types via a remapped keyboard layout. The "Hindi" in the system is, at the bytes level, mangled ASCII. Copy-paste into any Unicode-aware system produces gibberish. Search on a Krutidev field is broken for any non-trivial query. GST returns that pull these strings emit invalid UTF-8.
- Even with a Unicode font like Mangal, the text is rendered by the application's default GDI+ pipeline, which does not invoke Uniscribe shaping for
LANG_HINDIunless the developer explicitly opts in. Forms that look fine for ASCII silently truncate the second half of a compound consonant on render. - Receipts print broken ligatures. The thermal printer's escape-code path bypasses the screen rendering pipeline entirely; what gets sent to the printer is the raw codepoint stream, which the printer's firmware shapes (or doesn't) according to its own rules. The customer takes home a receipt where their name has the wrong vowel mark.
"Hindi support" in this category is not a language feature. It is a font-substitution hack that survived because the next thirty years of Indian retail software never demanded better.
§4 Forms-first means worker-hostile
The architectural assumption baked into every screen is: the user types everything.
Batch number. Expiry date in DD/MM/YY. Customer name. Drug strength. Pack size. Quantity. Discount percentage. The forms are dense, the keyboard shortcuts are arcane, and the data-entry tempo is set by how fast the operator's fingers can move.
This is a worker-hostile architecture. Not because forms are inherently bad — they're often the right answer for high-density expert use — but because the actual user is a 19-year-old behind the counter while a customer waits. He is not the system designer's imagined power user. He is the person whose mistake on a 12-character batch ID becomes the owner's headache at month-end reconciliation.
The "fix" most incumbents have shipped is a barcode scanner workflow for inventory, which works when the supplier prints scannable barcodes and falls back to typing the second that assumption breaks. The "fix" the next generation has to ship is a different interaction primitive entirely — one where you describe the thing in the language you'd use to describe it to a colleague, and the system drafts the structured record for you.
§5 "AI" as a marketing tile
A 2024–25 update across most incumbents added something labelled "AI". Inspecting the surface honestly:
- The most common implementation is a fuzzy-match button on the SKU search that runs Levenshtein over the local product table. This is useful, but it is not AI. It has been a standard feature in every IDE since 1998.
- A few vendors have added a "summarize this report with GPT" button bolted onto a screen no one was looking at. The button calls a hosted LLM with the visible table data and renders the response in a modal. The summary is correct, the workflow it sits inside is unchanged.
- One or two vendors have shipped a chatbot on their support portal. The chatbot helps with installation problems, not with running the shop.
Real AI capability in this category requires re-architecting around it. The conversation has to be the surface, not a feature inside a surface. The model has to read tools, not parrot dashboards. The draft has to be the artifact, not the chat reply. Bolt-on AI doesn't change the daily loop because the daily loop never went through the bolt.
§6 What the next pharmacy software is technically made of
The architecture that has to replace the WPF + MSSQL Express + ClickOnce stack is no longer experimental. It's been the default for the rest of B2B software for ten years. Translated to this category, it looks like:
- Cloud-resident, mobile-native client. The phone is the primary surface, the laptop is the secondary surface, the desktop is a courtesy.
- Per-tenant data isolation, encrypted at rest, durable. Each shop's transactional data lives in its own logical partition with its own key, on storage that survives the back-room PC catching fire.
- Conversation as a first-class interaction primitive. Type or speak in the operator's actual language. The screen and the form are specializations of the same underlying capability, not the baseline.
- Tamper-evident audit log on every write. Every state change is stamped, timestamped, exportable, and cryptographically not-after-the-fact-editable.
- Complex-text-shaping correctness. HarfBuzz on every render path, Devanagari conjuncts reordering correctly, receipts printing the right ligatures.
- Sub-2-second first paint on a low-end Android over 4G. Not a stretch goal — a release blocker.
- Self-serve onboarding. Open the link, you're in. No dealer, no install, no per-seat license key on a card.
None of these are individually radical. They are, line by line, the bar that every other B2B SaaS category cleared a decade ago. The pharmacy software category has the privilege of catching up to a settled architecture, not inventing one.
Closing
This post isn't a case against any one product. It is a case against a category that stopped being curious about its own technology in 2009 and got rewarded for the lack of curiosity by an SMB market that didn't know there was an alternative.
There is now.
— Akshat, writing this from Jabalpur