· Oladokun Oladapo · Building
What Leovidly runs on, and why
In case someone's wondering what Leovidly is built on. The few choices I'd defend, and the couple that cost me more than I expected.

In case someone is wondering what Leovidly is built on, here it is. I could just paste a list, but a list doesn't tell you much. What's actually interesting is the few choices I'd defend, and the couple that cost me more than I expected. I'll write proper deep-dives on some of these later. For now, the overview.
Kotlin Multiplatform, for a desktop app. This one's a bit odd. Most people use KMP to share code between iPhone and Android. I used it to build a Mac and Windows desktop app. I'm an Android engineer, so Kotlin and Compose are what I already know. I build the UI the way I always have, and the backend is Kotlin too, which means one language for the whole thing. The downside shows up when I need something the JVM desktop world doesn't just hand you. When I want a real browser inside the app, I bolt on Chromium through JCEF. Video playback runs on JavaFX, media processing on FFmpeg. So it's a native app with some heavy native bits taped to the side. I'd still make the same call.
I run the AI on your machine when I can. The default way to build an AI app is to send everything to a server, and Leovidly does a lot of that. But not all of it. Transcription happens locally with a bundled whisper.cpp. Background removal runs on-device with ONNX. It's faster, cheaper for me, and your audio never leaves your laptop. The catch is a heavier download, because I'm shipping real models and inference engines inside it instead of a thin client that phones home for everything. Fine by me.
Four AI providers, and yeah, on purpose. No single model is best at everything, so I stopped pretending one was. OpenAI does chat, and it also runs a moderation check before anything gets generated. Gemini is my default for images, Vertex AI is the backup. Voices come from ElevenLabs and Google's text-to-speech. Research runs on Perplexity. Is it more to manage? Yes. More keys, more things that break, more glue code. But each job gets the tool that's actually good at it, and you can see it in what comes out.
Signing was a whole project by itself. I did not see this one coming. Writing the app was the fun part. Getting it to install on someone else's machine without a scary warning took nearly as long. macOS wants an Apple Developer ID certificate and every build run through Apple's notarization before Gatekeeper will trust it. Windows wants code signing through SSL.com's cloud HSM. jpackage builds the DMG, MSI and DEB, and the signed installers get pushed to Cloudflare R2 with an update feed so the app can update itself. It's the least fun part of the whole thing, and it's most of what "shipping" actually means. I'll write this one up on its own, because I couldn't find a straight answer anywhere when I needed it.
The rest of it. Quickly, everything else holding it up:
- Desktop: Compose Multiplatform for the UI, Koin for wiring, Ktor for networking (and a small local MCP server so Claude can work inside the app), Coil for images, on JDK 21 and Gradle.
- Backend: Kotlin and Spring Boot, Spring Security with JWT for auth, MongoDB for data, Spring AI to reach the models, in Docker on Render.
- Website: Astro for leovidly.com, the blog and the docs, with Sanity as the CMS, on Netlify.
- Services: Resend for account email, Loops for the newsletter, Creem.io for payments, Google Drive for optional project sync, and Pexels, Pixabay and Openverse for stock B-roll.
- Keeping it healthy: GitHub Actions for CI, Sentry for crashes, Kotzilla for watching the internals.
That's the map. None of it was planned. Every piece got added the first time I hit a wall without it, which is why it's longer than the app looks. And it's not done. By the time you read this I've probably swapped something or bolted on one more.


