GetThrivin Mobile App
A native mobile learning experience — course pathways, video lessons, daily check-ins, achievement tracking, and push notifications — built for workforce development across African markets.
Overview
The mobile app is its own product. While the GetThrivin platform case covers the full stack — API, web, SAML, Coursera — this case is about the native side: what it took to build a learning experience that felt right on a phone, in a hand, on a spotty LTE connection somewhere in sub-Saharan Africa. I built it from scratch using React Native with Expo’s managed workflow, and it ships to both iOS and Android from a single TypeScript codebase.
The state model is built on Zustand — deliberately lightweight and serializable, which made the offline story possible without reaching for heavy solutions. Lesson progress, course completion flags, and daily check-in state all live in a local store that syncs to the API when connectivity is available. Video lessons are handled with a progressive-load strategy: low-res thumbnails load immediately, the video stream buffers ahead of the user, and completed segments are cached so a second watch doesn’t re-fetch. For learners in markets where data is metered and networks are unreliable, this isn’t a nice-to-have — it’s the baseline.
Push notifications run on both FCM for Android and APNs for iOS through the Expo Notifications layer, triggered by the BullMQ job system on the API side. Daily check-in nudges, streak reminders, and pathway completion milestones all flow through this pipeline. EAS Build handles the build and distribution pipeline: OTA updates for JS-layer fixes land to devices without a store submission cycle, while native-layer changes go through EAS-managed store builds. That split kept iteration velocity high throughout the project.
Architecture
Reading the diagram: The React Native / Expo app (center, violet) holds a Zustand local-first store for offline resilience — lessons and progress survive a network drop. EAS Build drives two delivery channels: full store builds for native changes, and OTA updates for JS-layer fixes. The app talks directly to the GetThrivin API core for course data, authentication, and progress sync. Push notifications flow from the API through FCM (Android) and APNs (iOS) and land on device — dashed return paths — triggered by BullMQ nudge jobs on the server side.
Six things shipped,
three hard ones solved.
Key contributions
- Architected and built the full React Native app from scratch using Expo managed workflow.
- Implemented course pathways, video lesson player, and achievement tracking with local-first state via Zustand.
- Designed offline caching layer so learners in low-connectivity regions could complete lessons without a live connection.
- Integrated push notifications on both FCM (Android) and APNs (iOS) through Expo Notifications.
- Set up EAS Build for automated OTA updates and production store builds.
- Built daily check-in flows and streak tracking to drive learner retention.
Challenges solved
- Reliable video playback and lesson progress on networks with poor or intermittent connectivity.
- Keeping a single React Native codebase that felt native on both iOS and Android without platform-specific hacks.
- Delivering a low-friction onboarding flow for workforce users who were not power-app users.
The mobile product isn't a web view in a shell — it's a native experience built around the constraints of the markets it serves. Offline first, push-first, one codebase.
What's under the hood.
Ready to fix, build,
or scale?
30 minutes, with me personally. I'll read your system like a log file and tell you what I'd do first. No pitch deck, no sales funnel.
— Davor Majc, founder, Numen