DEV Community

shaojie gong
shaojie gong

Posted on

GrowBook: shipping in 12 languages, and the boring gauntlet before Google Play

The code was done. The app worked. And then came the part nobody blogs about: the distance between "it runs on my phone" and "strangers can install it from the Play Store." That distance is longer than it looks, and it's paved with paperwork.

Two things ate this final stretch: languages and compliance.

First, languages. GrowBook ships in 12 of them. Not "we'll localize later" — twelve, in the box, from launch. That decision reshaped small things everywhere. My plant labels needed translations keyed by scientific name. My notification copy had to make sense in every locale. And Chinese alone is two of the twelve — Simplified and Traditional — which is how I ended up hand-writing a Simplified→Traditional character table for plant names, because I had Simplified data and Traditional users and no budget to translate hundreds of names twice. Android has a localeConfig for declaring supported languages so the system knows what you offer; filling it out honestly is a small file that represents a large amount of "did you actually check this screen in Arabic" work.

Then, compliance — the genuinely unglamorous part. A few things I learned the slow way:

  • Version numbers are two numbers, not one. Users see 1.0.0. Google cares about versionCode — an integer that must increase with every single upload. My first public version is 1.0.0, but internally it's versionCode 7, because there were six builds before it that only ever existed inside the Play Console. Every test upload burns a number. Nobody tells you this; you just watch the integer climb.
  • Signing is forever. Release builds are signed with a keystore, configured out of a keystore.properties file kept out of the repo. Lose that key and you can't update your own app — a new key means a new app. My build falls back to the debug signing config when the keystore is absent, so a teammate (or CI) can still build without holding the release secret. That fallback is a convenience that must never, ever run for a store upload.
  • The target API level is a moving deadline. Google requires new apps to target a recent Android API level, and that bar rises every year. Mine has a hard date attached: I have to be on the required target level by August 31, 2026, or updates get blocked. "Ship it and forget it" isn't a thing anymore — staying published is a subscription paid in maintenance.
  • Developer verification is now a gate, not a formality. Before your app reaches anyone, your developer identity has to be verified. It's a real checkpoint with real back-and-forth, and it's a step you can't compress by writing better code.

None of this is hard the way a light-sensor bridge is hard. It's hard the way taxes are hard: unfamiliar, unforgiving of small mistakes, and impossible to skip. The lesson I wish I'd internalized earlier is that "done" is a developer's word. The store has its own definition, and it includes a pile of forms, an ever-rising API target, a signing key you must guard for the life of the app, and an integer that only goes up.

GrowBook is 1.0.0 now — version code 7, twelve languages, offline-first, on the Play Store. The code was the fun 80%. This last 20% is why so many finished apps never actually ship.

If you've launched on Google Play: what caught you off guard in the final stretch — the API level treadmill, the signing paranoia, the version-code accounting, or something worse? I want to know what's still ahead of me.

https://growbookcare.com

— building GrowBook in public, #6

Top comments (1)

Collapse
 
raknaos profile image
Raknaos

The versionCode accounting is the trap nobody warns about: every internal upload burns an integer that only goes up, and by the time 1.0.0 reached a reviewer mine was already in double digits — a permanent record of every failed build, visible in the console forever. The signing paranoia is equally real; I treat the keystore like production credentials now, backed up offline and never in CI.

Your point about the debug-signing fallback being a convenience that must never run for a store upload is exactly right — that's the kind of default that quietly bites during a rushed hotfix. Did Google's pre-launch report catch anything real for you, or did it mostly burn quota on issues that never reproduced on a device? Mine kept flagging problems that no physical phone could trigger, and I never settled on how much to trust it.