Inspiration Family memories fade — the stories, the recipes, and especially the voices. When someone's gone, what people miss most is the sound of them. Journaling and genealogy apps are text-and-photo, single-device, and siloed per person. We wanted a voice-first way to capture everyday memories, preserve how people actually sound, and pass a whole family's story down across generations — on whatever phone each relative already carries.

What it does Kinlily is a voice-first family archive:

Journal by voice or text — capture a memory in seconds. Clone your voice behind a private consent gate, and hear AI-written stories narrated in your own voice. Build a multi-generational family tree — relationships, photos, and dated life stories. Ask Lily — an on-tree AI agent that answers questions about your relatives, and can speak the answer in a chosen family voice. Family recipes and a voice timeline of how you (and your family) sounded over the years. Hands-free with Siri and Google Assistant; private by design, encrypted end to end. Ships on iOS and Android, in 10 languages. How we built it One Kotlin Multiplatform core, two fully native front-ends. All business logic, networking, persistence, and i18n live once in shared Kotlin (sharedLogic/); the UI is SwiftUI on iOS and Jetpack Compose on Android so each platform feels 100% native.

MVI per screen — a shared Contract (Event/State/Effect) + ViewModel over a shared BaseViewModel. Ktor + kotlinx.serialization for one typed API gateway to an encrypted backend; SQLDelight for an offline read-through cache; Koin for DI; Coroutines/Flow everywhere. Native SDKs (Firebase auth/storage/FCM, telemetry, audio + on-device speech-to-text, Siri App Intents / Android App Shortcuts) are shared Kotlin interfaces wired per platform via expect/actual. Voice cloning and story/agent generation run behind the backend; every shared view-model is unit-tested in commonTest. Challenges we ran into Sharing everything but keeping the UI perfectly native — we chose native SwiftUI/Compose over a single UI toolkit to never compromise on polish, which meant a disciplined shared "brain / native skin" boundary. Relationships are only correct from one point of view — "maternal cousin" for one relative is "nephew" for another. We built a deterministic, viewer-relative edge-walk over the family graph so the same tree reads correctly for every member, instead of trusting an LLM to guess kinship. Cross-user voice — sharing a cloned voice for playback and narration required a real consent + governance model. Reliability at the edges — long-session token refresh, offline cache, and 1:1 iOS/Android parity from one codebase. Multilingual by person — each relative's mother tongue drives both story dialogue and how their cloned voice speaks. Accomplishments that we're proud of One Kotlin core → two polished, fully native apps live in both app stores. You can hear a departed relative again — clone a voice, then narrate their stories in it. Ask Lily answers real kinship questions grounded in your actual tree. Hands-free memory capture and family Q&A via Siri and Google Assistant. 10 locales plus per-person mother-tongue storytelling — and every view-model covered by shared tests that run once for both platforms. What we learned KMP is at its best when you share the logic and keep the views native — you get code reuse and platform-perfect UX. expect/actual + DI keeps platform SDKs clean and the shared layer pure. Kinship is deceptively hard; a deterministic graph walk beat LLM guesswork for correctness. Writing a feature once — and testing it once in shared Kotlin — genuinely halves the work and the bugs. What's next for Kinlily Cross-user voice narration with fuller consent/governance. A photo montage synced to the voice timeline, and word-level "karaoke" narration. On-device speech-to-text on Android, more locales with human translation. Family invite/claim at scale so relatives join and contribute to the same living tree. Exploring shared UI (Compose Multiplatform) and a lightweight web companion.

Built With

Share this project:

Updates

Submission history