Let's face it, most of us dread i18n. I know I do. It feels like wrestling with catalogs, boilerplate, and endless edge cases. So we avoid it when we can. And when we can't, readability suffers: what should be simple code quickly turns into a maze.
I ran into this while adding i18n to a sizable project with over 1K messages. At the time, out of the available options, Lingui was the better one to start with as it handled catalog generation automatically, which spared me a ton of manual work. And it didn't completely damage readability, because messages stayed in the code.
But as the project grew, I still found myself buried in boilerplate. Every new message added friction and extra complexity. The process felt heavy again. The tooling was helping, but also getting in the way. I didn't like this so much that I avoided adding i18n to another smaller project that could use it. I didn't want to go through it again.
This experience got me thinking: we already can tell if a piece of text in the code is going to be visible to the user or not. For example, text inside HTML tags is going to be shown. So why do we have to write extra boilerplate just to internationalize it?
That question sparked the creation of Wuchale, an i18n toolkit that does two things:
- Scans your plain code for user-visible messages, extracts/optionally translates them and then compiles them into compact keyless catalogs, just arrays, like Protobuf (more on this below)
- Automatically rewrites your code to get messages from the compiled catalogs by index, no keys required
It uses AST-based static analysis on your code, so it is very flexible; it will find your messages wherever they are. The result is that your source code stays clean and readable, while Wuchale handles everything under the hood:
-
Original code
<p>Hello</p>
-
Transformed code
<p>{_w_runtime_.t(0)}</p>
-
Extracted catalog (after translation)
msgid "Hello" msgstr "Hola"
-
Compiled catalog
// the message is at index 0 export let c = ["Hola"]
Like Protobuf, the compiled catalogs don't need metadata; the consuming code already knows the mapping. Moreover, the compiled catalogs are optimized at build time for runtime use; no string replace or anything complicated happens during runtime, even when using complex messages with interpolations and nested messages.
It started with just Svelte, and then in almost three months of more than full time dedication, it has gone through many iterations and improvements with feedback from the community, and has expanded its reach. It now supports React/Preact, Svelte, SolidJS and of course JavaScript/TypeScript (even for server-side messages).
But this is not the end. For the ultimate DX, HMR is key, and it has received a lot of care to make it work smoothly. You write your code as always and Wuchale keeps the catalogs in sync in the background.
And further still, you can optionally use AI to translate the messages for you. Of course this does not match the quality of human translators, but if you want something quick that you can revisit later, it can do the translations on-the-fly. This enables writing your code in English and seeing the results in another language in the browser!
With all of this, you might expect a lot of dependencies. Nope. One of the things I didn't like about Lingui was its huge dependency size for what I need. Wuchale has less than 10 dependencies and it shares most of the same dependencies with Vite and your framework (e.g. Svelte's own parser for parsing Svelte). That means the additional dependencies are less than 5 (including transitive ones).
I now enjoy working with it, it feels like it's never there. FYI, I went back to that project and fully internationalized it with Wuchale in under 30 mins, using Gemini for the translation. And most of that time was spent on the language selector UI.
So, what's next? The biggest update planned is support for other backend languages, Go and Python, so that even the messages from there are internationalized.
Interested? Check out the website or the repo and give it a try!
Thank you for reading and I hope you try it and enjoy working with it. And feedback is always welcome. Wuchale is fully open source and open to contributors.
Photo by note thanun on Unsplash
Top comments (0)