Go to content
cutty.dev
All posts

cutty.dev technology stack — conscious choices

What is under the hood of cutty.dev and why. No evangelism — the philosophy: a boring, stable stack, EU-based hosting, and privacy built into the architecture, which a single person is able to maintain.

Most "my tech stack" posts are a proud list of novelties. Look, I have this, I have that, and here is a brand new library from last week. This one will be different.

Because the truth is that when you run a project by yourself, you aren't looking for the trendiest. You are looking for something that won't wake you up at three in the morning. And that is exactly what this entire cutty.dev technology stack is about: boring instead of trendy, European instead of American, private from the ground up, and simple enough that a single pair of hands can handle it.

I'll go through it one by one, as if I were explaining it to you over coffee.

Astro rendered on the server (and why not something "cooler")

cutty.dev is Astro with server-side rendering. Every request goes through the server, assembles the page, and returns ready-to-use HTML. Boring? That's exactly the point.

I wanted three things: server-side rendering without heavy machinery, proper out-of-the-box multi-language support, and speed without overhead. Astro provides all of this, and the code remains readable. When I return to it after a two-month break, I know exactly what is going on there. For a solo project, this is worth more than any trendy plugin that no one supports after a year.

One file instead of a database with fireworks

SQLite. One database, one file on the disk. On top of that, a query layer talking to TypeScript, so if I change the data structure, the error pops up in my editor instead of in production at midnight.

Why exactly this? cutty is "read-heavy". Someone clicks a shortened link, we perform a read and increment the counter. That's it. SQLite handles such traffic easily, up to really large numbers daily. And backup? You copy the file. Done. Without replication ceremonies, without scripts that no one remembers how they work.

Be careful of one thing here, because it is a common trap: people hear "SQLite" and think "a toy for a passing project." That is not true. Fewer moving parts means fewer things that can break. This is not cutting corners on quality; it is a conscious decision.

The server is located in Europe and this is no coincidence

Dedicated server in the EU. Own TLS, reverse proxy with automatic HTTPS, application in containers.

This is the foundation of how cutty handles data. I know exactly where they physically reside (for EU and GDPR clients, this is not a curiosity, but a requirement), I am not tied to a single provider, nothing automatically leaks across the ocean, and the bill is predictable instead of jumping along with usage.

Yes, convenient platforms from the West would have provided a faster start. You click, deploy, it works. Only that you pay for it with where your users' data lands. For me, it was a bad deal.

Translations are made by their own model, on their own


cutty speaks 25 languages. This is translated by a local, open AI model that runs on my infrastructure. I do not send text from the interface to any external provider.

The benefits are practical. A single translation costs zero. I have full control over the quality and can refresh it whenever I want. And a machine always needs a human eye, so each of these 25 languages has been reviewed. But the fact that I do this myself means that privacy is not an item on a price list. It is a property of how the whole thing is built.

Tailwind, containers and a few smaller decisions

Style? Utility-first, meaning Tailwind. No CSS-in-JS, no separate style files, everything right in the templates. I don't waste time inventing class names; unused styles don't end up on the final page anyway, and the design holds together because the system itself enforces it. For a single person, every minute not wasted on trivialities counts.

This implementation is Docker. The same environment locally and in production, no more "it worked on my machine". And if it were ever necessary, I can move the whole thing to another server in about half an hour. Portability is a silent form of independence.

What I took from this

A boring stack wins. Astro, SQLite, Tailwind, containers. Everything is mature, well-tested, and documented. Nothing breaks at the moment when you least need it to.

Hosting in the EU is production-ready, truly. The idea that "you must go to the big American cloud to be serious" is a myth. Local AI is also real; you don't need to hand over data to an external API to get decent translations. And one last thing: one person can release something that looks like the work of an entire team. You just have to remember that time is more expensive than money, and choose every building block with that in mind.

When you are building something of your own, ask yourself one question with every technology: will I be able to maintain it myself in a year? If not, then you probably have your answer.

It all works here: cutty.dev. And if you want to talk about any of these decisions, write to [email protected], I reply the same day.