Linguito

Presenting Linguito, your AI-assisted companion for your app's translations
There are plenty of tools out there for internationalization (i18n), and it can take a while to find one that clicks with your workflow. For us, that tool turned out to be Lingui. It strikes a sweet spot between flexibility, ease of use, and compatibility in a way that feels just right for our projects. Some of the features we particularly like are:
- Rich-text support - You can define copies inside React tags, and the translation will include them for extra context. Common problems with links, bold text, or listing items are gracefully resolved using anonymous tags.
Lingui includes used tags inside the translation key to make working with rich-text so much smoother
- Plurals support - Nothing to add here, managing plurals is vital to any i18n effort.
- Extensibility - Lingui uses standard formats (
.po
) that can be plugged into your translation workflow easily.
This post isn’t a pitch for Lingui though. It’s more of a journal entry about what building Linguito taught us, the libraries we used, and why we think tooling plays such a huge role in enjoying the work we do.
Say Hi to Linguito
Check Linguito here
So why Linguito? Well, we’ve always had a soft spot for tooling—it’s like having a well-organized workshop where everything has its place, and when everything is tidy, you can spend more time on what really matters. While Lingui is solid as a rock, we noticed some gaps in our workflow that we felt could be easily addressed:
- Missing translations - We’ve made the mistake of publishing a version (or two) of our apps with untranslated strings. This happens because it feels very natural to use the final copies while coding, and we often forget about the extra step of translating them.
- Context loss - Catalog files are like words taken out of a conversation; they are stripped from the original context where strings are used. This makes the translation process a bit rough as you go back and forth between the app, the code, and the string being translated.
On top of that, we can’t emphasize how important tooling (as a concept) is to us. As a team that loves to kick off new projects like they’re going out of style, good tooling has become crucial to avoid the groundhog day feeling of doing the same tasks over and over again. Tooling turns that repetition into a continuous learning process where we can take note of the things that hurt the most and fix them for the next iteration.
The implementation
Because talking about how the tool is used would feel too rtfm-ish, we decided to talk about some of the libraries we used in this project and how they helped us create Linguito.
oclif
Our go-to library for building CLI tools. It’s not just a library but a framework that helps you with argument parsing, command taxonomies, error handling, testing, and much more.
$ linguito --help
CLI tool designed to enhance the capabilities of Lingui
VERSION
linguito/0.5.0 darwin-arm64 node-v22.12.0
USAGE
$ linguito [COMMAND]
COMMANDS
check Check for missing translations in catalog files.
config Interactively read and update the app's configuration settings.
format Cleans commented translations in catalog files.
help Display help for linguito.
translate Check for missing translations in catalog files.
Most of the content displayed here is part of the definition of commands inside the tool and is used to build amazing CLI experiences
Ink
This is the most esoteric library we used for Linguito. Imagine React but in the terminal—that’s what Ink does. At first it felt dirty bringing such a modern piece of technology to the terminal, but it ended up solving many usability issues and making the interactive mode in Linguito a delight.
We now feel building this UI without React would have been quite a journey
ai-sdk
Created by the Vercel team, the ai-sdk
package has become the standard for communication with LLMs using TypeScript.
The SDK handles the messy bits — streaming responses, error handling, and niceties like
structured output — which lets us focus on crafting
the right prompts and processing the results.
zod
Who doesn’t know Zod? It’s one of these omnipresent libraries you end up using in all projects, regardless of their nature.It lets you define schemas and validate data against them. Combined with the ai-sdk (and structured data) you can tell the LLM to respond in a very specific format, so that we don’t have to wrestle with it when it decides to add extra commentary or formatting that models sometimes love to include.
Our takes
After spending about a week putting all the pieces together, we’ve had some time to mull over the decisions we made along the way.
- Started local, expanded everywhere - We initially focused on local LLMs because there’s something satisfying about keeping everything self-contained on your machine. No API keys to manage, no rate limits to worry about, no exposure of sensitive information to third-party services, and your translation content stays right where you put it. But we quickly realized that different projects have different needs—sometimes you want the convenience and power of Claude or OpenAI, and sometimes a local model is perfect for the job. So Linguito grew to support both worlds. The flexibility to choose based on your specific situation and preferences feels like the right approach.
- Open source - Making Linguito open source wasn’t really a choice—it was just the natural way to go. The tool builds upon other open source projects, and keeping it open means anyone can peek under the hood, learn from our mistakes (there are plenty), or even better, point out ways to improve it. It’s like cooking with the kitchen door open—you never know who might drop by with a good suggestion for the recipe.
- Part of the work at the studio - This is one more building block in the foundation of Antropia, making the process of spinning up new React Native prototypes smooth as butter.
Looking back at this little journey, Linguito started as a scratch for our own itch but ended up teaching us quite a bit
about parsing .po
files, LLM integrations, and building proper CLI tools. It’s far from perfect—and probably always
will be—but it makes our day-to-day work with translations less of a hassle. If you’re working with Lingui and bump
into similar pain points, feel free to give it a shot or contribute your own ideas. The tool is still finding its feet,
and we’re curious to see how it evolves with real-world usage.
Happy translations!