Built a local-first mood journal in React Native — and the boring sync parts nearly broke it
Description and use
MoodMO is a local‑first mood journal built with React Native/Expo, offering optional Supabase sync and privacy‑focused design.
Problem
Need a private, single-player mood journal that records relationship context without forcing social or therapeutic framing.
Outcome
MoodMO delivers a private, local-first mood journal with optional cloud sync, respecting user privacy and avoiding common pitfalls of generic mood apps.
Workflow
- 1. Record entry locally in AsyncStorage as JSON.
- 2. Optionally sign in to enable Supabase sync.
- 3. Use Profile to upload (push) or pull data; pull replaces server‑shared IDs, push uploads rows with updatedAt newer than last sync.
- 4. Soft delete stamps deletedAt; permanent delete inserts tombstone in cloud table.
- 5. Widget (Soft Stack) displays weather/garden snapshot via App Group UserDefaults.
- 6. AI features run only if Groq key present at build time, sending aggregates to provider.
- 7. No telemetry or Sentry; data sent over HTTPS when synced.
Evidence
I built MoodMO for myself first, in React Native / Expo. It is currently published on the iOS App Store —not Android.
Local-first storage (and an honest at-rest gap). Entries live on-device first as JSON in AsyncStorage (guest key vs per-user key).
Optional sync uses Supabase when you sign in. Auth session tokens use SecureStore; diary entries do not.
Soft delete stamps deletedAt (recycle bin can restore). Permanent delete inserts a tombstone id for signed-in users; pull/push filter those ids so another device cannot resurrect a purged entry.
Upload and pull are separate actions—not one automatic pipeline.
Widget as hostile multi-process storage (iOS). Soft Stack never receives diary body, people names, or audio paths—only a whitelist snapshot.
- Record date: 2026-10-18T02:41:23.854Z