compare.matrix
How ngx-runtime-i18n compares
This is the library author's own comparison against ngx-translate, transloco, and Angular's built-in i18n, so read it with that in mind. Each row is sourced from the compared library's own documentation, release notes, or source code, and cells carry a verification date where the underlying fact can change between releases.
| Feature | ngx-runtime-i18n | ngx-translate | transloco | Angular built-in |
|---|---|---|---|---|
| Signals-first state | Yes — I18nService exposes lang, ready, and switching as signals from its first release | Yes as of v18.0.0 (2026) — currentLang, fallbackLang, and the pipe rebuilt on signals | Partial — translateSignal() added on top of an RxJS-observable-first TranslocoService | No — compile-time template markers, no injectable service or signal |
| SSR / hydration story | TransferState-based SSR-to-client handoff; catalog work is deferred until app stability so hydration never mutates the DOM early | Client-first; community guides describe wiring TransferState into a custom loader for Angular Universal, not a built-in SSR mode | Official SSR guide describes a custom synchronous loader plus a baseUrl for Angular Universal | N/A — no runtime catalog to hydrate; each locale is its own prerendered or server build |
| Fallback chains | Ordered array (fallbacks: string[]) tried in sequence before defaultLang | Single fallbackLang only — defaultLang/defaultLanguage were removed in v18 | Array-based via a custom TranslocoFallbackStrategy; open issues note edge cases where later entries in the array get skipped | None — an untranslated string falls back to the source-language literal at compile time |
| Type-safe keys | Yes — TranslationKey/TranslationParams are template-literal types inferred from the catalog shape, checked at compile time | No built-in typing — third-party wrappers (generic base classes, community toolkits) add key safety on top | No first-party compile-time typed keys — the separate Keys Manager (TKM) CLI validates key usage instead of the type checker | N/A — $localize tagged template strings, no key-based lookup at all |
| Per-route lazy catalogs | Yes — withI18nScope() loads a route-scoped catalog on activation and unloads it on destroy | Yes as of v18 — provideChildTranslateService() creates an isolated per-route/component child service with its own store | Yes — provideTranslocoScope() lazy-loads a translation file per feature or route | No — one compiled bundle per locale, no per-route split |
| ICU / plural support | Built-in ICU-lite formatter ({count, plural, ...}) ships in @ngx-runtime-i18n/core, no extra package | No native plural syntax — needs the separate ngx-translate-messageformat-compiler package (runtime eval-based) | Yes via the official @jsverse/transloco-messageformat plugin, not bundled in core | Yes — native ICU plural/select syntax in templates, resolved at compile time |
| Build-time vs. runtime switching | Runtime — fetchCatalog() loads a language on demand, no rebuild or reload needed to switch | Runtime — a TranslateLoader fetches catalogs; language switches without a rebuild | Runtime — same loader-based model as ngx-translate | Build-time — one compiled output per locale; switching languages means serving a different build |
| npm package maturity | 6 packages at npm 2.1.0 (core, angular, primeng, material, schematics, cli), confirmed via npm view on 2026-08-17 | @ngx-translate/core at npm 18.0.0, confirmed via npm view on 2026-08-17 | @jsverse/transloco at npm 8.4.0, confirmed via npm view on 2026-08-17 (successor scope to the deprecated @ngneat/transloco, stalled at 6.0.4) | Ships inside @angular/core and @angular/localize — no separate package to version |