What is Better i18n?
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 #
- You write
t("welcome.title")in your code - The CLI scans your project and sends the keys it finds to Better i18n
- Translations get written — by you, by AI, by whoever reviews
- You publish
- 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 #
| Package | For |
|---|---|
@better-i18n/next | Next.js — App Router, middleware, ISR |
@better-i18n/remix | Remix and Shopify Hydrogen — loader-based |
@better-i18n/vite | Vite apps, including TanStack Router |
@better-i18n/expo | React Native and Expo, with offline storage |
better_i18n (pub.dev) | Flutter |
@better-i18n/server | Node, Hono, Express — anything server-side |
@better-i18n/sdk | The primitive the others are built on |
@better-i18n/cli | Scanning, syncing, publishing, CI checks |
What is different from JSON files in a repo #
| Files in your repo | Better i18n |
|---|---|
| A string change is a deploy | A string change is a publish |
| Translators need repo access, or you paste for them | They get an editor, scoped by role |
| Missing translations surface in review, or in production | Coverage per language, and a CLI check that fails CI |
| Machine translation is a script someone ran once | AI translation with your glossary and page context |
| Keys are managed in code only | Code, dashboard, or an AI agent over MCP |
Better I18N