i18next
One translation library for the Vite apps, the Next.js sites, emails, and backend errors.
Why i18next
Bones renders text four ways: in the browser with Vite, in Next.js server and client components, in emails rendered by the backend, and in the backend's own error messages. i18next's core is a plain function, t(key, english), with no compile step, so the same approach works in all four. react-i18next is a thin layer on top for React.
The i18n workspace wraps both. It exports createT and getT for server code, useT and I18nProvider for React, the language table, and the date and number formatters.
Why not the others
- Lingui worked in the web app, then broke the marketing site. Its compiler plugin failed on Next.js 16.3.6 under both Turbopack and webpack. The plugin is tied to Next.js's internal compiler version, so every Next.js upgrade could break it again.
- Paraglide can't keep the English in the component, and fixes messages at build time.
- next-intl only runs in Next.js, so
shared-uiand the Vite apps would need a second system. - FormatJS would also work everywhere with no build step. It lost on verbosity and momentum.
Monthly npm downloads on 2026-09-24, with a year earlier in brackets: react-i18next 53.9M (27.7M), next-intl 19.0M (3.9M), react-intl 10.6M (8.9M), @lingui/core 5.3M (2.2M), and @inlang/paraglide-js 1.8M (0.26M).
English inline
The English lives at the call site, as the key or as the default value. Bones never loads an English catalog at runtime, because a loaded catalog would override the inline text and leave two copies that can disagree. A missing or empty translation falls straight through to the inline English.
i18n/locales/en/*.json still exists, generated from the code, for translators to work from.
Why i18next-cli
i18next-cli reads the code and writes the catalogs, so nobody edits a key list by hand. Its linter finds interface text that skips t(), and CI runs both.
Dates and numbers
Formatting uses the browser's built-in Intl APIs, with no library. The language comes from Bones and the region from the browser.
Flags
The language pickers show each language's flag, from country-flag-icons, as SVGs. Emoji flags render as letters on Windows. Each flag is imported by itself, so only four ship.
Used in
- Internationalization — what's translated, and what isn't.
- Internationalization — adding and translating a string.