← Default view
Runtime core with locale chunks splitting off — schematic emblem
React · i18n · RSC · Vite · Next.js
Bundle · Tree-shake · Lazy locale chunks
Sheet 04 / 05 — Decision framework: React i18n · 2026

Framework & Runtime Fit

Where six libraries sit in the runtime — compile-time vs runtime-dictionary, plotted across the Vite SPA and Next.js App Router / RSC paths.
Drawing
Runtime-Fit
Depth
Survey
Libraries
Six
References
19
React
19 · RSC
Rev
2026·07·15
General note

The runtime dictates the choice more than features do. React 19 is a non-issue — all six work with it. The real axis is RSC, bundle, and lazy-loading. Next.js App Router / RSC → next-intl or Lingui; Vite SPA → Paraglide (smallest) or react-i18next (ecosystem).

A

The controlling axis

Architecture → client bundle
plotted by weight
← Runtime-dictionary Compile-time →
react-intl
~20 KB+
ICU runtime · heaviest
react-i18next
~6 KB
+ full namespace
Lingui
~3 KB
+ compiled catalog
next-intl
~4 KB
457 B server-only
typesafe-i18n
~1 KB
+ codegen
Paraglide
~1 KB/loc
flat as catalog grows
Runtime-dictionary — load a JSON/ICU catalog, resolve keys through a lookup layer at runtime. Bundle scales with the catalog; RSC needs workarounds. Compile-time — emit typed functions ahead of time. Unused messages tree-shake; Server Components call plain functions, no React context.[1][7]
B

Two runtimes, two paths

Where the translation
resolves & what ships
Path 1 · Client

Vite SPA

No RSC — everything is client-side, hydrates normally. Axis = bundle + DX.

  1. 01 · Source

    Locale catalogs

    JSON / ICU / message files, one per locale, in the repo.

  2. 02 · Build (Vite)

    Compile vs. bundle

    Compile-time libs emit tree-shaken typed functions; runtime-dictionary libs bundle the catalog behind a lookup layer.

  3. 03 · Ship

    One client bundle + lazy chunks

    Vite splits locales natively via dynamic import() — the initial bundle carries one locale, others load on demand as chunks.[11]

  4. 04 · Browser

    Hydrate → DOM

    All translation work happens in the client; the payload is what the axis in Detail A measures.

Smallest, catalog-independent: Paraglide — 47 KB where i18next ships 205 KB, and stays flat 200→1000 messages.[7] A real migration dropped ~40 KB of i18next to ~2 KB.[14]
⚠ Skip next-intl here — it isn't built for a standalone Vite SPA; the docs make no mention of non-Next.js usage.[4]
C

Parts list

Per-library spec plates
runtime · ssr · lazy · bundle
Runtime-dict
⭐ 10k · core i18next ⭐ 8.6k
React 19
RSC-native
⚠ createInstance / wrapper
SSR
✓ mature
Lazy locales
✓ manual · http-backend / import()
Client bundle
~6 KB + namespace
Best fitVite SPA & Pages Router; the deepest plugin ecosystem.[1]
Runtime-dict
⭐ 15k · FormatJS · highest-starred
React 19
RSC-native
⚠ needs use client
SSR
Lazy locales
⚠ manual dynamic import
Client bundle
~20 KB+ ICU runtime
Best fitApps that genuinely need rich ICU (plurals/dates/currency) and can absorb the weight.[15]
Compile-time
⭐ 5.8k · macro extraction
React 19
RSC-native
✓ React cache
SSR
Lazy locales
✓ compiled catalogs
Client bundle
~3 KB + catalog
Best fitOne identical Trans/useLingui API across RSC + client — if you'll wire the SWC macro.[8]
Compile-time
⭐ 4.3k · App Router native
React 19
RSC-native
✓ getTranslations
SSR
Lazy locales
✓ per-locale · AOT server
Client bundle
~4 KB / 457 B server-only
Best fitNext.js App Router — the reference choice. ⚠ Not for a standalone Vite SPA.[4]
Compile-time
⭐ 567 · opral/paraglide-js
React 19
RSC-native
✓ pure functions
SSR
Lazy locales
✓ compile-time tree-shake
Client bundle
~1 KB/locale · 47–144 KB total
Best fitVite SPA where bundle size is the priority — size stays flat as the catalog grows.[7]
Compile-time
⭐ 2.5k · codegen-first
React 19
RSC-native
✓ plain TS fns
SSR
Lazy locales
✓ generated per-locale import
Client bundle
~1 KB + codegen
Best fitTS Vite SPA valuing codegen + strict param checking. ⚠ Momentum thin — last major release 2023.[12]
D

Specification by runtime

Pick the path first,
then the library
If the target is a

Vite SPA

  • ParaglideSmallest, catalog-independent bundle via compile-time tree-shaking.
  • react-i18nextThe deepest ecosystem — if you'll manage namespace splitting yourself.
  • typesafe-i18nWhen you want codegen type-safety. Vite handles all three's lazy locale chunks natively.
§

References

19 sources
Blueprint view · Atlas · canonical → Runtime-Fit · Sheet 04/05 · Rev 2026·07·15