meta

This Site Is a Monorepo, One Cookie and Two Languages

· 3 min read · Kaan Demirel · updated Aug 24, 2026

This site started as a writing habit, but what keeps it running is the setup rather than the habit. No database, no CMS, no admin panel. Everything lives in the repo, and publishing a post means a git commit.

Here is what that setup actually looks like now.

What I write about

I write about what I build: tools that run local-first or self-hosted, work where AI is a controlled component rather than a magic layer, and automation that survives contact with reality.

I also write about the things that did not work. After I stopped a SaaS experiment, the useful thing left over was not the product but the mistake, and that turned out to be easier to read than a success story.

The notes I promised about hermes-fact-store are here too: why one SQLite file was enough to give an agent memory is its own post now.

The shape of the site

The repo is not a single Astro project. It is an npm workspace:

  • apps/site, the site you are reading
  • apps/showcase, the project list at showcase.aethrox.me
  • packages/shell, the header, footer, design tokens and project data that both sites share

Changing something in packages/shell changes both sites at once. That is the point: two headers and two themes had already started drifting apart before this package existed.

Posts live in apps/site/src/content/blog/. A post with images gets its own folder; the rest are a single file.

Every post ships in two languages

A published post is not one file but two: .en.md and .tr.md. What pairs them is not the filename but the slug they share. If one of them is missing, a test fails and the site does not build.

The English text is not a translation. Both versions claim the same thing, but each one is written to be read in its own language, because a literal rendering goes stiff on one side or the other.

A test holds the mechanical half of the house style too: typographic apostrophes in Turkish, no long dashes anywhere, a fixed form for the terms that lose their meaning in translation. Whether a sentence says anything is still on me.

The JavaScript

The whole thing builds to static HTML and ships almost no JavaScript. Almost, because it is not zero.

Your theme and language preference live in a single cookie on .aethrox.me. Because both sit in one place, the preference comes with you when you cross over to the showcase, and the page opens in the theme you picked instead of flashing white first.

The rest is small: a theme button, a language button, a filter bar on the showcase. Nothing framework-shaped runs the page.

What comes next

Most of what lands here comes from the Rust and Python side: CLI tools, MCP servers, and the Linux desktop I use every day. That is the whole setup; the rest is writing.

posts