Performance Benchmarks
Why Performance Matters for i18n
Section titled “Why Performance Matters for i18n”Traditional i18n libraries ship an ICU MessageFormat parser to the browser. On every render, the parser must tokenize the message string, build an AST, resolve plurals and selects, then interpolate values. This work repeats for every message, every re-render.
Fluenti moves parsing and compilation to build time. At runtime, messages are either static strings or pre-compiled functions. The cost is reduced to a hash-map lookup and a function call.
Key Numbers
Section titled “Key Numbers”These are representative results from CI (ubuntu-latest, Node 22). Click the CI link above for the latest verified numbers.
Build-Time (runs once during pnpm build)
Section titled “Build-Time (runs once during pnpm build)”| Operation | Throughput | Takeaway |
|---|---|---|
| Parse plain text | ~8M ops/sec | Entire catalog parsed in milliseconds |
| Parse complex ICU (nested plural+select) | ~240K ops/sec | Even worst case is fast |
| Compile to function | ~20M ops/sec | Near-instant for all message types |
| CLI compile 500 messages | ~665 ops/sec (~1.5ms) | Sub-second for real-world catalogs |
| CLI compile 16 locales × 200 msgs | ~100 ops/sec (~10ms) | Linear scaling |
Runtime (happens in the browser)
Section titled “Runtime (happens in the browser)”| Operation | Throughput | Takeaway |
|---|---|---|
| Pre-compiled function call | ~10M ops/sec | This is what Fluenti ships |
| Static string lookup | ~4–13M ops/sec | Framework-dependent |
| Plural resolution (cache hit) | ~1–1.5M ops/sec | Intl.PluralRules + cache |
| Catalog lookup (10K messages) | ~18M ops/sec | Size doesn’t matter |
| Number formatting | ~1.4M ops/sec | Intl.NumberFormat + cache |
| Date formatting | ~980K ops/sec | Intl.DateTimeFormat + cache |
Framework Comparison: t() Lookup
Section titled “Framework Comparison: t() Lookup”| Message type | React | Vue | Solid |
|---|---|---|---|
| Static string | ~4.4M | ~3.8M | ~12.8M |
| Compiled function | ~10.7M | ~8.3M | ~9.7M |
| Single variable | ~3.8M | ~3.2M | ~3.1M |
| Plural (ICU) | ~1.4M | ~1.4M | ~1.5M |
| Nested plural+select | ~920K | ~890K | ~900K |
ops/sec — higher is better
Compile-Time vs Runtime Parsing
Section titled “Compile-Time vs Runtime Parsing”| Approach | What happens at runtime | Per-render cost |
|---|---|---|
| Traditional (vue-i18n, react-intl) | Parse ICU → build AST → resolve plurals → interpolate | Full parse + interpolation |
| Fluenti | Hash-map lookup → function call | Lookup + call |
For {count, plural, one {# item} other {# items}}:
- Traditional: ~910K ops/sec (parse every render)
- Fluenti: ~10M ops/sec (lookup) + ~1M ops/sec (pre-compiled plural) — 5–10x faster, widening to 40x on complex messages
Reproduce Locally
Section titled “Reproduce Locally”# Run all benchmarkspnpm bench
# Run core benchmarks onlypnpm bench:coreBenchmark files: packages/core/bench/, packages/cli/bench/, packages/{react,vue,solid}/bench/