Skip to content
fluenti

Introduction

Fluenti is a compile-time internationalization library for modern frameworks. It supports Vue, React, and SolidJS, with Svelte planned. It eliminates the three biggest pain points of traditional i18n: manual key management, runtime parsing overhead, and clunky rich text APIs.

Every i18n library asks you to invent a key for every string:

// en.json — you maintain this by hand
{
"pages.home.hero.title": "Welcome to our app",
"pages.home.hero.subtitle": "The best tool for ...",
"pages.home.cta": "Get started"
}

Keys drift out of sync. Unused keys pile up. Developers spend time naming things instead of building features.

Fluenti’s answer: the source text is the key. Write <h1 v-t>Welcome to our app</h1> and extraction happens automatically. No JSON file to maintain.

Traditional libraries ship a full ICU parser to the browser, parsing message strings on every render. For a page with 50 translated strings, that’s 50 parse calls before the user sees anything.

Fluenti’s answer: the v-t directive is a Vue nodeTransform — it rewrites your template at build time. The compiled render function contains the translated string directly. At runtime, there is nothing left to parse.

Need a link inside a translated sentence? Most libraries force you into one of these:

<!-- vue-i18n: raw HTML injection -->
<p v-html="$t('click_here', { link: '<a href=\'/docs\'>here</a>' })" />

Fluenti preserves your actual markup. Translators see HTML they already understand, and there is no XSS vector.

Featurevue-i18nLinguiFluenti
KeysManual key stringsAuto-generated IDsSource text = key
Rich textv-html (XSS risk)<0>indexed</0> placeholdersNative <a>, <strong>, etc.
Runtime costFull parser in bundleCompiled messagesCompiled + v-t zero-cost
Code splittingManualManualBuilt-in locale chunks
Catalog formatJSON onlyPO / JSONPO / JSON
SSRPlugin config requiredCustom setupBuilt-in locale detection
FrameworksVue onlyReact onlyVue, React, Solid
ICU MessageFormatPartial supportFullFull
FormattersSeparate @intlify/coreExternal packagesBuilt-in d() / n()

Fluenti’s pipeline turns your source text into optimized, per-locale bundles at build time:

Source code Extract Catalog Translate
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ <h1 v-t> │ ───► │ fluenti │ ───► │ .po │ ───► │ Poedit / │
│ Hello! │ │ extract │ │ catalog │ │ Crowdin │
│ </h1> │ └──────────┘ └──────────┘ └──────────┘
└──────────┘ │
Ship Compile Translated
┌──────────┐ ┌──────────┐ ┌──────────────────────────┐
│ Vite │ ◄─── │ fluenti │ ◄─── │ .po catalog with target │
│ bundle │ │ compile │ │ language strings filled │
└──────────┘ └──────────┘ └──────────────────────────┘
  1. Write source text directly in your templates: <h1 v-t>Welcome</h1> or t`Hello!`

  2. Extract messages with fluenti extract — scans Vue SFCs and TSX files, generates PO catalogs

  3. Translate using any gettext-compatible tool (Poedit, Crowdin, Weblate) or translate the PO files by hand

  4. Compile with fluenti compile — generates optimized JS modules, one per locale, ready for code splitting

  5. Ship — Vite bundles compiled translations automatically via @fluenti/vite-plugin, with static or dynamic locale loading

Fluenti’s compile-time architecture provides fundamental performance advantages over runtime i18n libraries:

AspectRuntime librariesFluenti
Bundle sizeShip ICU parser + runtime (15-40 KB)No parser shipped — compiled messages are plain functions
Parse costParse every message on renderZero parse cost — messages are pre-compiled strings/functions
Rich textRuntime DOM manipulation or v-htmlCompiled at build time into static render instructions
Code splittingManual per-locale setupBuilt-in splitting: 'dynamic' with automatic chunk loading

The v-t directive in Vue is a nodeTransform — it rewrites your template during compilation, so the translated string appears directly in the render function. There is literally nothing left to execute at runtime for static translations.

For dynamic messages (with variables, plurals, or selects), Fluenti compiles ICU patterns into small functions that perform string concatenation — no parsing, no AST traversal, just direct value interpolation.

PackageDescription
@fluenti/coreFramework-agnostic ICU parser, compiler, interpolation, plural/select, and formatters
@fluenti/vueVue 3 plugin: v-t directive, <Trans>, <Plural>, <Select>, useI18n() composable
@fluenti/reactReact integration: I18nProvider, <Trans>, <Plural>, <Select>, useI18n() hook
@fluenti/solidSolidJS integration: I18nProvider, <Trans>, <Plural>, <Select>, useI18n() hook
@fluenti/cliMessage extraction (Vue SFC + TSX), PO/JSON catalog format, compilation
@fluenti/vue/vite-pluginVite plugin for Vue: build-time v-t transforms, compile-time `t“ optimization, and locale chunk loading
@fluenti/react/vite-pluginVite plugin for React: compile-time `t“ optimization and locale chunk loading
@fluenti/solid/vite-pluginVite plugin for SolidJS: compile-time `t“ optimization and locale chunk loading
@fluenti/nuxtNuxt module: locale-prefixed routing (4 strategies), SEO helpers, composables
@fluenti/vue-i18n-compatProgressive migration bridge — run vue-i18n and Fluenti side by side
Terminal window
pnpm add @fluenti/core @fluenti/vue
pnpm add -D @fluenti/cli
Terminal window
pnpm add @fluenti/core @fluenti/react
pnpm add -D @fluenti/cli
Terminal window
pnpm add @fluenti/core @fluenti/solid
pnpm add -D @fluenti/cli
Terminal window
pnpm add @fluenti/nuxt @fluenti/core @fluenti/vue
pnpm add -D @fluenti/cli
  • Node.js >= 18
  • Vue >= 3.4 (for Vue bindings)
  • React >= 18 (for React bindings)
  • SolidJS >= 1.8 (for Solid bindings)
  • Vite >= 5 (for Vite plugin)
  • Nuxt >= 3 (for Nuxt module)