Mobile apps for iOS and Android — SvelteKit + Capacitor or React Native.
Germany / Remote. Open to good work.
I’m Dominik. I’m a computer science student. Most of what I ship right now is mobile — iOS and Android apps, built either with SvelteKit and Capacitor or with React Native, depending on what the project needs.
TypeScript end to end. TailwindCSS for anything that needs a face. I care about latency budgets, small teams, and writing that doesn’t waste your time.
I write here about what I’m building and what I’m reading. The site is intentionally low-bandwidth and high-contrast. I think most modern websites are too loud.
Not exhaustive. Not a mandate. Just what’s in muscle memory right now.
A companionship experience with a tracker attached. Tsuki is a Rive-driven character threaded through onboarding, tracking, social, and AI surfaces — backed by a Rust GraphQL monolith and a PyTorch recommender.
Two apps so far. UmtilScrub strips EXIF metadata from photos and videos entirely on-device. UmtilNote is a bubble-based note app where every thought lives one day, then disappears unless you pop or archive it.
Short essays on engineering, tooling, and stopping on time.
I am not anti-AI. I use it every day, and the work I ship is better and faster for it. What I am against is the thing I see happening to a specific cohort of newer developers — the ones who started coding one or two years ago, in the middle of the AI boom, and who never built the muscle that comes before the AI does anything useful.
That muscle is reading code. Debugging code. Sitting with a bug for an uncomfortable hour and walking out of it actually understanding why it happened. If you skipped that part, AI does not make you faster. It makes you a printer for code you cannot read, and a printer that confidently prints the wrong thing is a worse tool than a slow human who can tell when something is off.
I have been writing code for eleven years. The reason I can use AI well now is that I spent the first nine without it. I know what a fishy stack trace looks like. I know what “this function is doing too much” feels like before I can articulate why. When the model hands me forty lines, I am not accepting them — I am reviewing them, the same way I would review a teammate’s PR, and I reject things constantly.
The cohort I worry about cannot do that review. They paste, they run, it works, they move on. When it breaks — and it always breaks eventually — they paste the error back into the chat and hope. There is no model under the hood. There is no instinct for where bugs live. There is just a slowly growing pile of code nobody, including the person who shipped it, actually understands.
This is not a moral failing. It is a training-data problem in their own heads. They are missing the years of exposure that turn raw output into a thing you can evaluate, and the only fix is the boring one: write code without the model sometimes, on purpose, and sit with what is hard about it. Not because AI is bad. Because being able to read what it gives you is the entire job now.
Early on, design felt like the layer you put on top of an app once the app worked. Pick a font, pick a color, round some corners, ship. I do not think that anymore.
The thing that changed my mind was watching the same engineering decision get easier or harder depending on whether the design was in place first. A screen that has been laid out properly tells you what state it needs. A screen that has not been laid out yet asks you to invent state speculatively, and most of the state I have ever invented speculatively has been wrong.
So now I treat design as architecture. The wireframes are the rough draft of the data model. The empty states are the rough draft of the error handling. The transitions are the rough draft of the loading logic. By the time I open the editor, half of the engineering decisions are already pinned down, and the half that remain are the ones I actually want to spend time on.
This is, I think, the unfair advantage of building both halves yourself. You do not have to translate between two people who are looking at the product through different lenses. You only have to be honest with yourself about which lens you are using when, and switch when the work asks you to.
I am not against MVPs. Shipping the smallest version of an idea, putting it in front of people, learning from what comes back — that is still the right loop. I follow it. I just notice that when I run that loop, the M in my MVPs ends up larger than the M in most other people’s.
UmtilSuite is the clearest example. It is, by my own honest accounting, a minimum viable thing. I cut everything that did not need to be in the first version. And the result was still a multi-tool suite, because the smallest viable answer to “what does this product need to do” was not a single feature — it was a small but coherent set of them.
Tsukime is a different category. Tsukime is not an MVP. It is a deliberately big project, built slowly, and I am not pretending otherwise.
I think the trap with the “ship small” rule is taking it as an aesthetic — like the smaller the launch, the better the engineer. The actual rule is “ship the smallest version that is still a real answer to the problem.” Sometimes that is one screen. Sometimes that is a suite. The discipline is being honest about which one you are looking at, and not shrinking past the point where the thing stops working.
I started writing code at twelve. Game dev first, because that is what twelve-year-olds want to make. Then Discord bots, then Telegram bots, then desktop clients, then web apps, and now mobile. Eleven years, give or take, with the shape of the work moving every couple of years.
Design showed up later. I was sixteen when I started taking it seriously, which means I have been designing for about seven years and coding for eleven. The order matters. By the time I cared about type, color, and layout, I already had years of muscle memory for how software actually gets built, and design slid in next to that instead of replacing it.
The reason I think this is worth writing down is that the two skills have very different decay rates. Code skill rots fast — the framework I was excited about at fourteen is gone, the bots I wrote at fifteen run on APIs that no longer exist. Design skill compounds slowly. The hierarchy decisions I was making at seventeen still hold up. The instinct for what is loud and what is quiet on a page does not need to be re-learned every two years.
So I keep both halves running. The code half stays sharp because the work demands it. The design half stays sharp because, once you have it, it is cheap to keep — and it makes everything the code half produces look like it was made on purpose.
Updated by hand every couple of weeks. Inspired by nownownow.com.
Mostly nights and weekends, but really whenever an idea grabs me hard enough to open a new repo.
Projects usually die one of three deaths: scope creep, quietly drifting away once the idea stops matching what I had in my head, or the dread of writing App Store and Play Store listings — screenshots, copy, all of it.
Hot take: most devs still cannot work with AI for shit — and that is a skill issue, not a model issue.
More sample collector than bottle collector — I would rather try fifty decants than commit to one full bottle.
Signatures by temperature: Versace Eros Flame (very cold), Parfums de Marly Layton (cold), Xerjoff 40 Knots (warm), Versace Pour Homme EDT (hot).
Will die on the hill that Naxos is overrated, and that Angels’ Share / Kamrah just smells like alcohol with no finesse.
Best via email. I read everything eventually.