Skip to content
better-i18n.com

Better i18n keeps your translations out of your repository and serves them from a CDN, so changing a string does not mean shipping a build.

That is the whole idea. Everything below is a consequence of it.

The loop #

  1. You write t("welcome.title") in your code
  2. The CLI scans your project and sends the keys it finds to Better i18n
  3. Translations get written — by you, by AI, by whoever reviews
  4. You publish
  5. Your app fetches the new strings at runtime

Steps 4 and 5 are where the difference lives: there is no rebuild between them. A typo fix reaches production in about a minute, and it does not need a deploy window or a developer.

What you are working with #

Project — one app or site, addressed as org/project (acme/dashboard). Keys, languages, and settings belong to it.

Key — an identifier like common.save_button with one value per language. The part before the first dot is its namespace, which is also the unit your app can load on its own — a page that only needs checkout does not have to download admin.

Source language — the one your code is written in. Every translation is produced from it.

How delivery actually behaves #

Published translations are served from Cloudflare's edge with max-age=60, which sets the honest expectation: up to a minute between publishing and every visitor seeing it, not "instantly".

Publishing also purges the cache for what changed, so in practice it is usually faster than a minute. The TTL is the ceiling, not the wait.

The SDKs layer their own caching on top — in memory, and on device for mobile — so a network blip does not leave your app without strings. There is a fallback bundle for the cold start case too.

SDKs #

PackageFor
@better-i18n/nextNext.js — App Router, middleware, ISR
@better-i18n/remixRemix and Shopify Hydrogen — loader-based
@better-i18n/viteVite apps, including TanStack Router
@better-i18n/expoReact Native and Expo, with offline storage
better_i18n (pub.dev)Flutter
@better-i18n/serverNode, Hono, Express — anything server-side
@better-i18n/sdkThe primitive the others are built on
@better-i18n/cliScanning, syncing, publishing, CI checks

What is different from JSON files in a repo #

Files in your repoBetter i18n
A string change is a deployA string change is a publish
Translators need repo access, or you paste for themThey get an editor, scoped by role
Missing translations surface in review, or in productionCoverage per language, and a CLI check that fails CI
Machine translation is a script someone ran onceAI translation with your glossary and page context
Keys are managed in code onlyCode, dashboard, or an AI agent over MCP