Groundbase
← Back to the Pipeline
Notes

Why Groundbase is three apps, not one

Web, Windows desktop and Android, built and maintained by one person. Here is the reasoning, the tax it charges every single week, and the rule I had to invent to stop it going wrong.

Groundbase is three applications. A web app, a Windows desktop app, and an Android app. One person builds all of them.

Most advice would call that a mistake. Pick a platform, ship one thing well, add the others when you have a team. It is good advice and I ignored it, and I want to write down both why and what it has actually cost — because the cost is larger than I expected and I still think the decision was right.

The reason: three different jobs

The mistake is thinking of them as the same product on three screens. They are not. They are three genuinely different moments.

Desktop is for the two hours you actually work the CRM. Importing a list, cleaning up records, building an invoice, working through a pipeline. Heads-down, keyboard, a real window. A browser tab is fine for this; a dedicated window you leave open all day is better, and it does not disappear when you close the wrong tab.

Mobile is for four seconds in a car park. Someone rings. You need their name, what you last said, and whether they owe you money, before the second ring. That is the entire mobile use case, and building a phone app around it produces something quite different from a shrunken desktop.

Web is for everywhere else — a borrowed laptop, a machine you cannot install software on, the first five minutes of a trial when nobody is downloading anything.

If I had built one, it would have been the web app, and the car park moment would have been a responsive layout that technically works and that nobody would actually reach for.

The tax, stated honestly

Every change ships three times.

Not "the backend is shared so it's basically free" — genuinely three times. Three UIs, three sets of state handling, three sets of platform quirks. A change that takes an hour on web takes closer to three across the board, and the third one is always the one you do while bored.

And they do not deploy the same way. The web app ships when I push. The desktop app needs a build and a manual upload. Android needs its own build with its own version bump. So the moment I finish something, the three apps are already out of sync, and they stay that way until I package the other two.

The failure mode this creates is drift, and it is worse than the extra work. A fix lands on web, feels finished, and the other two quietly keep the bug. Nothing tells you. There is no build that goes red, no test that fails. You find out when you open the app on your phone weeks later, hit the same problem you fixed, and briefly wonder whether you imagined fixing it.

I have done that several times. The desktop app's own CSV export wrote custom-field columns that its own importer then silently dropped — export and re-import, and that data was gone, for months, with no error. A filter on the deals board existed in one app and not another. Each time the fix was small and the delay was entirely because nothing surfaced the gap.

The rule I had to invent

Eventually the pattern was obvious enough that I made it a rule with no exceptions: every change ships to all three in the same pass. Not "web now, desktop later" — later is what created the backlog the rule exists to prevent.

The build-and-upload step still gets batched to the end of a run of work, because packaging installers after every small fix is its own kind of waste. But the code goes in everywhere at once, or it does not go in.

The second half of the rule matters as much: when a platform genuinely cannot take a change, say so explicitly and write down why. Mobile has no CSV import and never will — a spreadsheet on a phone is not a thing anyone wants. It has no invoice builder, because line-item editing on a five-inch screen is a punishment. Those are decisions. Without recording them, a deliberate absence looks identical to an oversight, and six months later nobody can tell which they are looking at.

The part I got wrong

I assumed the desktop app would be a thin shell around the web app. It is not, and that is the single most expensive assumption I made.

Desktop does some of its work in the Electron main process, talking to the database directly rather than going through the API the web app uses. There were reasons at the time, mostly about speed and about working with local files. The consequence is that a server-side fix does not automatically reach desktop, because desktop is not always asking the server.

That is the actual source of most of the drift above. Not laziness — an architectural difference I did not think through, in a place where "these are the same app" felt obviously true and was not.

If I were starting again I would make the desktop app a genuinely thin client and accept the performance cost, because I have now spent far more time on divergence bugs than that cost would ever have amounted to.

What I would tell someone else

Three apps is affordable if the backend is genuinely shared and the clients are genuinely thin. Everything expensive here came from the places that turned out not to be either.

Do not do it for coverage. "Be everywhere" is not a reason. Three different moments in someone's week is a reason. If you cannot name the distinct job each platform does, you want a responsive web app and an early night.

Write down the deliberate gaps. The cheapest thing on this list, and the one I did last.

There is a related honesty problem worth naming: the desktop app is unsigned. Windows shows a SmartScreen warning on install, and I have decided to live with that rather than pay for a certificate at this stage. It is a genuine rough edge, and telling people about it in advance is better than having them discover it at the worst moment.

Was it worth it

Yes, but narrowly, and mostly because of mobile.

The car park moment is real, it happens constantly, and a responsive web page would not have earned the home-screen icon. Desktop I am less certain about — it is better than a browser tab for long sessions, but it is the one I would drop first if I had to.

The honest summary is that three apps cost me roughly twice what one would have, bought one genuinely irreplaceable use case, and taught me an architectural lesson I would rather have learned by reading it somewhere. Which is why it is written down here.

For more on the trade-offs of building this alone, see why I built Groundbase as a solo dev. The infrastructure half of the same argument is in why I chose Cloudflare Workers over Vercel. And if you want the version that says who this product suits and who it does not, that is here.


Building something across multiple platforms on your own? I would genuinely like to hear how you are handling it: blog-three-apps@groundbasecrm.com — I read every one.

Built by a solo dev. Try it.

Start your 14-day trial →

More from the Pipeline

Notes

Why I'm not marketing Groundbase on LinkedIn

Most indie marketing advice eventually arrives at "you should be on LinkedIn." Here's why I deliberately wo…

Notes

Why I killed Groundbase's credits system and went BYO Twilio

The "platform credits" model looks great on a pricing page. Behind the scenes it's a maze of compliance ove…

Guides

How to warm up a new email domain (a four-week schedule, and what actually gets you filtered)

You verified the domain, the DNS is green, and your first campaign still went to spam. Warming is the missi…

Guides

When a spreadsheet stops working as a CRM (six signs it already has)

A spreadsheet is a perfectly good CRM for longer than most people admit. Here are the specific signals that…