Divyd

Sole Engineer
Shipped
App Store · 5.0 rating

Bill splitting and P2P payments app, designed and built solo from zero to the App Store. Maintaining a 5.0 rating.

Divyd is a bill splitting and peer-to-peer payments app I designed and built solo, from scratch through to the App Store. Split a bill with friends, track who's paid, settle up in-app. The premise is simple. The implementation required a lot of careful thinking about what happens when a mobile app gets interrupted.

The client is Expo/React Native with 49 screen routes, Zustand for local state, TanStack Query for server state, and a custom API client with GET deduplication and client-side rate limiting on top of a production REST backend.

Divyd App Store listing or home screen

Session Management Across the App Lifecycle

The hardest frontend problem in Divyd isn't the bill logic. It's keeping authentication state correct across every way a mobile app can be interrupted.

When a user puts the app in the background and returns thirty seconds later, they should still be signed in. When iOS kills the process overnight and the user cold-launches in the morning, they should be signed out and asked to re-authenticate. When they're away for ten minutes and come back, it depends on the idle policy. Three different scenarios, three different correct behaviors, and the only difference is how long it's been and whether it was a true process kill or just a background.

The session manager handles each case explicitly. A timestamp in secure storage records the last moment the app was active. On resume, elapsed time is compared against a configurable idle threshold: short gaps don't trigger logout, long ones do. On cold start (process kill and relaunch), the system clears auth state unconditionally, regardless of token expiry, because a cold-started token could be arbitrarily old without the expiry timestamp reflecting that.

The cold-start check runs exactly once per process launch using an in-memory flag. Without that guard, navigation during launch can trigger the check multiple times and cause unexpected logouts mid-flow.

Divyd bill split creation flow

Unified Activity Feed

The activity tab shows a single unified feed of bills, but the API returns them across three separate shapes: bills you created, bills you're a participant in, and recurring bills, each with different fields and different available actions.

A single hook merges all three into one normalized type, deduplicates by ID, and applies category filters (all bills, paid, pending, recurring) on the merged result. The user sees one clean list. The complexity of three separate API shapes is entirely contained in the data layer.

Divyd activity tab showing bills

Auth and Onboarding

Divyd supports three sign-in methods: email/password, 4-digit PIN, and Google OAuth with PKCE. PIN login exists alongside password login because re-authenticating after an idle timeout on mobile is friction. A short numeric code keeps the security boundary without demanding a full password every time the session expires. Onboarding tracks email verification and PIN setup as independent steps and routes new users through whichever is incomplete before granting access to the main app.

Divyd auth or onboarding screens

0
App Store rating
0
screen routes across auth, bills, wallet, friends, notifications
0
sign-in methods: email, PIN, Google OAuth with PKCE
0
API shapes unified into one normalized activity feed

Tech Stack

React NativeExpoTypeScriptExpo RouterTanStack QueryZustandexpo-secure-storeexpo-notificationsexpo-auth-sessionPostHogZod
Lagos, Nigeria