I’ve been using Kotlin since 2016 or 2017. I use it primarily for Android apps development, and to share rules and models between iOS and Android sometimes. I enjoy writing in Kotlin - it’s a good language that allows using different styles and approaches and a lot of great things, really.

For back-end and internal tools it was used only once, on a project that had been started a bit before I joined - to manage mobile release cycles. Ktor proved to be a great tool to write a fast solution but it required the JVM and at that time we could use it on our servers. But sometimes we are restricted by security policies or limited by resources.

And that’s when other tools were called for small tasks. I started with Bash (and spent hours debugging why it worked locally on macOS but not on linux CI), next try was Python, and ended with Go. Go is amazing - I don’t need anything else to solve my little DevOps-like tasks for mobile development, no external deps, fast sync, fast build and expected and reproducible behavior (Hello, Bash). It was great from some perspective, like I was forced to learn a lot of things starting from tools to systems. But it was stressful, to be honest.

All that time I had high hopes for Kotlin Multiplatform, and specifically Kotlin/Native. But every time I got stuck with setup or runtime issues. When Ktor 2 was released with the CIO engine - I tried it again. It worked better than before but the number of unsupported features was a dealbreaker for me. And again I was forced to use JVM (Oh, no!) if I wanted a smooth experience.

Time goes fast - it’s 2026 and I decided to try GraalVM native images with Kotlin and Ktor. It works, but it’s still overkill for a small app in my humble opinion. It’s still hard to compare with Golang or Rust (in case of set up and environment). While researching the topic, I found Katcher - an error tracker built in Kotlin/Native by Pavel Votyakov. That’s a good showcase and an interesting project. Pavel also wrote blog posts (EN/RU) about his experience building it. He inspired me to take another round. So it’s time to try pure native again.

I’m not that creative and couldn’t think of anything better to build than a to-do list app, for a few reasons:

  • It’s kind of challenge for me, I want to close this Gestalt and move on :)
  • I need something to work on between jobs.
  • I’m not banning LLMs from this project, but I prefer to write it by hand - it’s more fun that way. I’m not trying to launch a startup or make money. Just for fun.
  • CRDT, I want to try implementing it for a long time, so it fits here too.
  • My partner sometimes asks me to keep track of things, and it’s a bit complicated to manage. We used Telegram before, but messages sometimes got lost in the chat history, and Telegram doesn’t work well in Russia right now so we couldn’t rely on it the way we used to. There are tons of solutions for this kind of problem - you don’t need to build your own, unless it’s interesting, fun, or a learning experience (like this one).

This time I want to build it in public - welcome to the to-do list graveyard. I also want to write some feedback on the process - maybe it will be a simple “It’s alive!” or maybe I’ll get stuck again somewhere. We’ll see.

That’s all for today, have a good life, folks.

P.S. I use LLM to check and iteratively fix grammar and sentence structure, English isn’t my best skill (to be honest my native language skill is pretty rough too, I still feel sorry for my Russian teacher - she put in a lot of effort, but I never quite reached the level she hoped for). I also used it to review the content and that’s funny sometimes:


### 1. You describe what happened, not what you learned

> *"I started with Bash... next try was Python, and ended with Go."*

This reads like a timeline. A senior engineer would frame this as a **decision**, not a journey:

> *"Bash is fine until it isn't — the moment you need consistent behavior across macOS and Linux CI, you're debugging quoting rules at midnight. Python was better but felt heavy for glue scripts. Go hit the right balance: single binary, predictable behavior, no runtime surprises."*

That's the same story, but it shows judgment, not just sequence.

My personal blog - my journey.