Inspiration
"Wait — was it coffee they couldn't drink?"
We kept forgetting the small details that carry a relationship: a friend's favorite sweets, a colleague's kid's name, what we talked about last time. Contact apps store phone numbers, not people.
Enlog (縁ログ — en means a personal bond in Japanese; the two overlapping rings in the logo are two people's circles meeting) is a notebook for those bonds.
What it does
- People profiles — name, photo, birthday, likes & dislikes, custom fields, free-form notes
- Meeting log — when, where, and what you talked about, with keep-in-touch reminders when too much time has passed
- Photo attachments — up to 3 photos per log entry, with a full-screen swipe viewer (asked for by a beta tester; see below)
- Birthday & anniversary alerts via local notifications (day-before alerts for Premium)
- Calendar view — a month grid of everyone's birthdays and anniversaries (this one was chosen by a public vote; see below)
- Gift log — what you gave and received per person, thank-you tracking, up to 3 photos per gift (v1.9.0 — the runner-up in that vote)
- Suggestions — cards on the home screen computed from your own notes, on this device: a gift hint for an upcoming birthday, a keep-in-touch alert that has passed, a thank-you gift still pending, someone you have not seen for longer than usual, and profiles that are still empty. Free shows 2, Premium shows them all (v1.11.0, shipped September 15)
- Search, tags, groups, favorites, light/dark/system themes, JA & EN
- Sample data — one tap on the last onboarding screen fills the app with example people, so you can explore before writing anything
- Private by design — records live in an on-device SQLite database. No account, no server, no ad SDK, no analytics SDK. The only things that leave the phone are purchase information (Apple / Google / RevenueCat) and, if you choose to answer the one-time in-app question about where you heard of Enlog (added in v1.10.0), that single answer, sent anonymously to RevenueCat.
- Enlog Premium — unlimited people, day-before alerts, unlimited custom fields, unlimited gift records, JSON backup & CSV export
How I built it
- Expo SDK 57 / React Native 0.86 + TypeScript, expo-router, expo-sqlite — offline-first
- RevenueCat (react-native-purchases v10) runs all monetization: one entitlement (
premium), an Offering with monthly / annual / lifetime packages. The paywall renders live store prices from Offerings, and entitlement state gates every freemium limit. - Built almost entirely with Claude Code — from trademark screening of the name, to App Store Connect automation over the ASC API (products, prices across 175 territories, metadata, review submission), to the script that renders the two-ring icon.
Building in public actually changed the app
This is the part I did not expect.
Published August 7. Thirteen updates in the next twenty days — ten of them came straight from user feedback or public votes. By September 1 that was fifteen App Store releases (v1.9.0 added gift tracking — the runner-up in the feature vote), and on September 5 the same version went live on Google Play.
- A store review said anniversaries silently failed to save. Reproduced it against the SQLite file, fixed it, and shipped the same day.
- A review asked for anniversary sorting and per-anniversary notification toggles. Shipped three days later.
- Someone on X reported the keyboard covering the note field. Fixed in the next release.
- A reviewer wrote that the note field was hidden behind the keyboard. Digging into it, the real defect was worse than reported — on small screens the save button itself was unreachable, and tapping outside discarded the draft with no confirmation. All three are fixed and shipped.
- Another reviewer asked for input suggestions on custom fields, because typing them by hand made the labels drift ("favorite brand" vs "favourite brand"). That shipped too.
- A Google Play beta tester pointed out that the Birthdays tab had no way to add a birthday, and asked to import phone numbers from contacts. Both shipped the next day.
- Another beta tester said text-only logs were hard to skim back through — "with a photo I'd instantly remember where we met." Photo attachments shipped in v1.7.1, and v1.8.0 added a full-screen swipe viewer the day after.
- The Android closed test produced six reports in two weeks; five shipped (the sixth was declined, with a reason), and the app went to production with all of them in.
- Two reviewers whose bug reports were fixed came back and updated their store reviews.
I also let people vote on what to build. The first vote picked the app icon (70 votes) — the winning design shipped in v1.4. The second vote picked the next feature, and calendar view won with 40%. I implemented it the same day I announced the result — about two and a half hours from poll close to a working screen.
Challenges I ran into
- Subscription prices don't propagate across territories. The ASC API needs one POST per territory; I scripted all 175 from USD equalizations.
- StoreKit returns introductory-offer info even to users who aren't eligible. Show it blindly and you promise "7 days free" to someone who will be charged in full. Eligibility has to be checked separately.
- OpenSSL 3's default PKCS#12 silently breaks Apple code signing.
-legacyis required. - A screen that never worked, hidden behind the wrong error message. "Import from contacts" showed "contacts access not allowed" even when access was granted. The permission call returned
granted; the real failure was a deprecated API throwing — and acatchthat reported every error as a permission problem. Nobody reported the broken search box on that screen, because nobody could reach the screen at all. - The photo-attachment limit is a backup problem, not a paywall. Manual backup embeds images as base64 inside one JSON file, so unlimited photos would quietly make export impossible. Three per entry keeps backups working — and the app warns instead of silently dropping what doesn't fit.
What I'm proud of
- A solo, fully localized (JA/EN) app with working subscriptions, shipping every few days
- A paywall that showed live App Store prices on the first try, thanks to RevenueCat
- Privacy architecture with zero data collection beyond purchases — and store copy that says exactly that, no more
- Turning feedback around in hours, not sprints. That, more than any single feature, is what building in public gave me.
What's next
- Google Play release — shipped September 5. Closed testing (Aug 17 – Sep 3, 12 testers) → production access approved in 2 days → live worldwide in 177 countries. Launched both platforms on Product Hunt on September 8
- Relationship insights — shipped September 15 (v1.11.0). The first step is rule-based and runs entirely on the device (see Suggestions above); the next step builds on the same on-device data — nothing leaves the phone
- Widgets and a watch glance for today's birthdays
Built With
- android
- claude-code
- expo-router
- expo.io
- ios
- react-native
- revenuecat
- sqlite
- storekit
- typescript