A tale about IntlString: how a typealias and an office inside-joke helps us approach internationalization

Intlstring
A tale about IntlString: how a typealias and an office inside-joke helps us approach internationalization
Almost every team has its inside jokes. Ours happens to be about… internationalization. Yes, the thing most developers dread: endless translation files, locale fallbacks, and mysterious i18n bugs. But for us, whenever someone says “IntlString”, there’s always a little laugh. it sounds like “እንጥል ስትሪንግ” — which literally means uvula. Once you’ve heard that, you can’t un-hear it.
How IntlString was born
we started with the classic approach to translations. Different frameworks, different conventions, and too much boilerplate. “Do we really need this much machinery just to store some text in different languages?”
So we stripped it down to the basics. IntlString is just a map of locale → text. Nothing more. But the beauty is: we can use the exact same idea everywhere in our stack.
In Kotlin: with composition locales
On Android, we define:
typealias IntlString = Map<SupportedLocale, String>
Our SupportedLocale
enum holds values like EN_US
and AM
Then we can just write:
val title: IntlString = mapOf(
SupportedLocale.EN_US to "Hello",
SupportedLocale.AM to "ሰላም"
)
Text(title.getValue(LocalSupportedLocale.current))
No complex framework, no magic. If a locale is missing, we fall back to English. Done.
In React: plain and simple
On the frontend, we keep the same spirit with TypeScript:
export type Locale =
| "EN"
| "AM"
| "EN-US"
| "AM-ET"
| "en"
| "en-us"
| "am-et";
export type IntlString = Record<Locale, string>;
Then, in component:
const title: IntlString = {
"en": "Hello",
"am-et": "ሰላም"
};
return <h1>{title[userLocale]}</h1>;
It’s almost too simple to explain — and that’s exactly the point.
In Go: keeping it minimal
Go doesn’t have type aliases in the same way, but a map works perfectly:
type IntlString map[string]string
And then we can do:
title["en-us"]
title["am-et"]
No fuss, no ceremony.
In Prisma: JSON fields to the rescue
Even in our database models, we try to keep the same format. In Prisma we use Json fields:
model Subscription {
id BigInt @id @default(autoincrement())
label Json
description Json?
duration Int
basePrice Float
tier Int
specs Json?
active Boolean
visible Boolean
}
So a subscription label can look like:
{
"en": "Premium Subscription",
"am-et": "ፕሪሚየም አባልነት"
}
From database to frontend to mobile — the same IntlString travels unchanged.
Why we love it
IntlString started as a quick hack and an office joke. But it ended up becoming a unifying concept across our stack. Instead of dealing with heavy i18n frameworks in each layer, we agreed on one thing:
Texts are just maps from locale to string.
That tiny agreement saved us countless hours and made the code easier to follow. And, honestly, it kept the mood light. Because no matter how tough the sprint is, it’s hard to stay too serious when someone says:
“Did you remember to update the እንጥል ስትሪንግ?”
Sometimes, the simplest ideas bring both the most joy and the most clarity. IntlString is our little reminder of that.