[self-promo] I built an i18n compiler for SvelteKit where the source string is the key
Hi all,
I've been working on yapyak, an open-source i18n compiler that runs as a Vite plugin. There are adapters for a few frameworks, but SvelteKit is the one I use myself.
The idea is that the source string is the key:
<script lang="ts">
import { t } from 'yapyak';
</script>
<button>{t('Download recovery key')}</button>
You save the file, and the source string shows up in your locale files as an empty stub. If you've set up a translator, it gets auto-translated and written back, using call-site context (the component and the code around the call). HMR picks it up in the running app.
The video is a small example of that. I add a download button to a dialog and hit save. The German page is sitting right next to the English one, so I see it the moment it lands: Wiederherstellungsschlüssel herunterladen pushes the button row 97px past the edge of the dialog.
So I fix it right there, one prop on the button group.
That's a small slice of what yapyak does, but it's the part I use most. Translating stops being something I come back to later. It just happens on save.
Because it runs in the compiler, it sees more than the string itself. It reads ICU parameters out of the string literal, and it keeps track of a translation when you move or rename the source file.
In the SvelteKit SSR adapter, locale state is scoped per request on the server and uses Svelte's reactivity on the client. Switching locale is synchronous, since the translations a module uses get compiled into it. A fixed-locale build can compile t() away entirely and leave just the translated string.
Auto-translation is optional. There are shipped translators for Anthropic, OpenAI, Gemini and Ollama, all using your own API key, or you can leave the stubs empty and hand-edit the locale files.
I built it for a product I'm working on, and that's the whole business plan. There's no follow-up post where I get to the pricing.
MIT licensed, and still pretty early.
If you've done a lot of i18n in SvelteKit, especially SSR or anything big, I'd like to hear what you'd try to break.