Am vrut să-mi rezolv o problemă personală și am sfârșit prin a lansa o aplicație mobilă de habit tracking în Google Play și App Store. După 30 de zile avem puțin peste 200 de utilizatori activi, strânși organic. Nu e vreo cifră astronomică, dar a fost destul cât să-mi dea peste cap câteva presupuneri tehnice.
Stack-ul tehnic: De ce am mers pe simplu
Am vrut să livrez repede, așa că am ales Expo (SDK 50 la momentul respectiv) cu React Native. Baza de date e locală, direct pe dispozitiv, folosind WatermelonDB. Pentru sincronizare parțială și analytics am aruncat în spate un VPS ieftin de 4 euro pe lună de la Hetzner cu un Node.js chior și SQLite.
Trade-off-ul e evident. WatermelonDB e genial pentru performanță offline și liste lungi, dar configurarea inițială e un coșmar pe Android, mai ales la partea de native modules. Dacă aș lua-o de la capăt pentru un MVP, probabil aș folosi direct Expo SQLite sau chiar simple JSON-uri stocate în MMKV dacă datele nu ar fi relaționale.
Prima palmă: Notificările locale și timezone-urile
Aplicațiile de habit tracking trăiesc și mor prin notificări. "Hei, nu uita să bei apă!". Am zis că scap ieftin cu notificări locale programate direct din telefon. Mare greșeală.
Când userul schimbă timezone-ul sau când sistemul de operare (în special pe Xiaomi sau Samsung) decide să omoare procesele din background pentru a economisi baterie, notificările mele locale pur și simplu nu mai porneau. Am avut o rată de fail de aproape 15% în primele două săptămâni. Am rezolvat-o parțial forțând userii să treacă printr-un ecran de configurare a bateriei, dar experiența e destul de neplăcută. Soluția reală pe termen lung e push notifications trimise de pe server prin FCM/APNS, dar asta înseamnă costuri suplimentare și complexitate pe care voiam să o evit.
Caching-ul de stare și React Query
Pe partea de UI, m-am încăpățânat să folosesc Context API pentru starea globală a obiceiurilor pe ziua în curs. La 5 habit-uri e ok. Când un user hyper-activ și-a pus 25 de habit-uri zilnice și a început să le bifeze rapid, aplicația a început să agațe vizibil pe un telefon de buget de acum 3 ani.
Am rescris tot managementul de stare pe Zustand combinat cu React Query pentru ce trăgeam de pe server. Randarea a scăzut de la 120ms la sub 15ms pe un ecran cu multe elemente interactive. Am economisit cam 80% din re-randările inutile.
Ce aș schimba dacă aș lua-o de la zero
În primul rând, n-aș mai face sync-ul custom. Am pierdut 3 weekenduri scriind un algoritm de reconciliere a conflictelor (offline-first) când puteam folosi pur și simplu Supabase sau direct o bază de date locală fără sync în prima lună. Utilizatorii nu vor neapărat sync între tabletă și telefon la început; vor doar să nu le dispară datele dacă își reinstalează aplicația.
În al doilea rând, aș integra analytics mult mai devreme. Am lansat-o "pe orb" și primele 10 zile n-am știut de ce renunță lumea la onboarding. Abia după ce am pus PostHog am văzut că 40% din oameni se blocau la ecranul unde le ceream să-și creeze primul obicei fiindcă input-ul nu avea autofocus și tastatura acoperea butonul de "Next" pe ecranele mici.
Voi cum gestionați offline-first-ul în aplicațiile mici? Mergeți pe varianta simplă local-only până validează piața, sau construiți arhitectura de sync de la început?