Skip to main content

Why keyless i18n is the future

· 10 min read
Founder of i18n-keyless

Every i18n library you've used — i18next, react-intl, Lingui, FormatJS — is built around the same primitive: the translation key. You name a string, you reference it from code, you map it to translations in JSON files. This pattern has dominated for over a decade.

It made sense at the time. It doesn't anymore.

This is an opinion piece about why the assumption that you need keys is outdated, and why keyless i18n is the natural shape for modern engineering teams.

TL;DR

  • Translation keys exist because of constraints that don't apply to most modern teams: separate translator workflows, batch translation pipelines, and the lack of inline AI translation.
  • Modern AI translation is good enough for product UI strings that the "human translator in the loop" workflow can be inverted — translate first, review only the misses.
  • Once AI handles the first pass, keys stop adding value. They only add cost: naming, syncing, maintenance, missing-key bugs.
  • Keyless i18n is what the workflow looks like when you remove the key abstraction and let the source string be the lookup.
  • The argument for keys is now isolated to specific scenarios (TMS workflows, ICU plural rules, brand-glossary enforcement). For the majority of product UI, keys are a relic.

How we got here: a brief history of the translation key

To understand why keys feel necessary, you have to understand the workflow they were designed for.

1990s–2000s: GNU gettext. UNIX-flavored apps used _("Welcome") macros. The English string was the key. Sound familiar? gettext was, in retrospect, a primitive form of keyless. Translation tools (POEdit, Lokalize) consumed .po files keyed on source strings.

2010s: structured i18n libraries. Web frameworks (Rails, then JavaScript libraries) introduced namespaced keyst("homepage.hero.title"). Why? Because:

  • JSON files were easier to ship to translation pipelines than POT files.
  • Namespaces let you reuse keys across pages.
  • A canonical key meant you could refactor the source string without re-translating.
  • Translators worked in TMS tools that needed structured input.

2010s–2020s: TMS-driven workflows. Tools like Lokalise, Crowdin, Phrase emerged. They wanted keys + translations + metadata: glossaries, screenshots, translator comments, approval state. Keys became more than identifiers — they became the unit of translation work.

2023+: capable AI translation. GPT-4, Claude, Mistral, etc. produce translations of product UI copy that are competitive with paid human translation for short strings. The "human translator does the first pass" assumption — which justified TMS workflows — became negotiable.

The keys-everywhere convention was an answer to a workflow constraint. The constraint loosened. The convention persisted by inertia.

What keys actually cost you

If you've never sat down and counted, the cost of a key-based system on an engineering team:

1. Naming overhead

Every string needs a unique, hierarchical name. Teams disagree on conventions (hero.title vs pages.home.hero.title vs homePage.heroTitle). New engineers spend a month learning the convention. Refactors trigger naming arguments. Pull requests have "rename confirm_button to confirm_payment_cta" comments.

2. Synchronization overhead

Add a key in en.json, forget to add it in fr.json and de.json, ship a [hero.title] placeholder bug. Delete a key in one locale, forget the others, accumulate dead keys. Multiply this across every string change for the lifetime of the app.

3. Code review overhead

Reviewers can't tell what t("checkout.confirm.cta") says without opening a JSON file. Diffs that change copy don't show the actual change in the diff. Code review devolves into "let me check what this key resolves to."

4. Onboarding overhead

New engineers spend their first week learning where keys go, the naming convention, the namespace structure, and the build pipeline that ships locale files. Some never fully internalize it and just grep for similar strings.

5. Tooling overhead

You need a key-extraction tool, a missing-key linter, a CI step that validates locale-file integrity, a TMS integration to push/pull, sometimes a custom Babel/SWC plugin. This is a real maintenance surface.

6. Bug class: silent stale strings

The most insidious cost. Update the English string in code, forget to invalidate the French/German translations, ship outdated copy in non-English locales. Because the lookup still resolves (the key didn't change), no error fires. Users in non-English locales see stale copy.

What you actually gain from keys

Be honest — keys do provide real value in some workflows:

TMS-friendly format. Translators want keys + source + target — that's the unit they work on. If you have translators, keys are useful.

Translation memory across deploys. Change the English copy without re-translating, by keeping the key stable.

Glossary enforcement. "When you see the key subscription, it must translate as abonnement in French." Keys make glossaries enforceable.

ICU plural rules. Keys + ICU MessageFormat let you encode locale-aware plural logic in a single string.

Static analysis. Linters can detect missing keys, unused keys, malformed plural patterns.

These are real benefits. But notice the pattern: they all assume a translation workflow that has translators in it. If your translation workflow is "engineer ships, AI translates, occasional manual override," none of those benefits apply to you.

The keyless alternative

The keyless premise is simple: let the source-language string be the lookup. No naming, no JSON files, no synchronization.

// Key-based
<button>{t("checkout.confirm.cta")}</button>

// Keyless
<button><I18nKeyless>Confirm payment</I18nKeyless></button>

What changes:

  • No key naming. The source string identifies itself.
  • No locale files. Translations live in a backend, accessed at runtime, cached locally.
  • AI translates new strings. Cache misses trigger an AI translation, cached forever.
  • You override when AI gets it wrong. Manual overrides via the dashboard.
  • No missing-key bugs. There are no keys to mismatch.

The trade-offs are real:

  • You lose static analysis of "missing keys" (because the bug class doesn't exist).
  • You lose ICU plural-rule resolution (you branch explicitly in code instead).
  • You lose TMS workflows (because there are no JSON files to feed a TMS).
  • You depend on a backend (a SaaS dependency).

For teams without translators, those trade-offs are net-positive. For teams with translators, they're net-negative — stick with keys.

Why this hadn't happened earlier

Three things had to be true simultaneously:

  1. AI translation had to be good enough. Pre-2023, machine translation for product UI strings was usable but flawed enough that human review felt necessary. Modern LLMs cleared that bar.

  2. Caching had to be cheap and reliable. A keyless system needs a backend that caches translations per source string per locale. That's now table-stakes infrastructure.

  3. Engineering teams had to outnumber localization teams. Most JavaScript shops in 2026 don't have a localization team. The audience for "engineer-driven multilingual" is now the majority of the market — pre-2020, it was a minority.

All three conditions hold now. The keyless workflow is the rational response.

Objections, addressed

"But I want my translations in my repo for auditability."

Fair, in some compliance contexts (regulated industries, government). For most products, "translations live in a backend" is no different from "user data lives in a database" — your code doesn't ship with your user table either. The backend exposes export endpoints if you ever need a snapshot.

"AI translation isn't good enough for our brand voice."

For long-form marketing copy, yes — AI is good but not perfect. For product UI strings (buttons, labels, modals, errors, notifications), it's competitive with human translation. Plus you can override anything manually. The honest position is: keyless is excellent for product UI, less ideal for marketing copy.

"What if the translation backend goes down?"

Cached translations keep serving. New strings render in the source language. No errors. The graceful degradation is intentional — keyless is never worse than "show the source language."

"We need ICU plural rules for Polish/Arabic/Russian."

Yes, ICU is genuinely better at this. Use react-intl for that part of your app, or branch explicitly with Intl.PluralRules. Keyless doesn't claim to dominate ICU.

"Won't AI translation cost more than free locale files?"

For free locale files you've already paid translators to produce, sure. For new strings? AI translation costs cents per string. Realistic comparisons need to include the engineering time saved by not maintaining locale files — which is usually larger than the AI translation cost.

"Isn't this just gettext rebranded?"

Spiritually similar — gettext also used the source string as the key. Different in that gettext expected human translators feeding .po files; keyless expects AI generating translations on cache miss. Different infrastructure, similar primitive.

What this means for the i18n landscape

If you accept the premise, the i18n landscape splits into two categories:

Category 1: TMS-driven workflows (translators in the loop). i18next, react-intl, Lingui, paired with Lokalise, Crowdin, Phrase. Keys are a feature; locale files are the source of truth; translators do the work.

Category 2: Keyless workflows (engineers ship, AI translates). i18n-keyless, possibly future entrants. Source strings are the key; translations are infrastructure; engineers don't manage localization as a workflow.

Most products will pick one or the other based on team shape, not based on technical merit. There's no winner — they're tools for different organizations.

The interesting prediction: the proportion of products that need TMS workflows shrinks every year. Indie SaaS, AI-powered apps, vertical tools, no-code-adjacent products — these dominate new product launches and they overwhelmingly don't have translators. Category 2 is the growing market.

Try it

If this argument resonates and you want to feel the difference:

npm install i18n-keyless-react

Five minutes from now, your app speaks more languages than it did when you started reading this article. See the quick-setup guide.

Next steps