Introduction
Fluenti is a compile-time internationalization library for modern frameworks. It currently supports Vue and SolidJS, with React and Svelte planned. It eliminates the three biggest pain points of traditional i18n: manual key management, runtime parsing overhead, and clunky rich text APIs.
Why Fluenti exists
Section titled “Why Fluenti exists”The key management tax
Section titled “The key management tax”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.
Runtime parsing overhead
Section titled “Runtime parsing overhead”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.
Clunky rich text
Section titled “Clunky rich text”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>' })" />{/* Lingui: numbered placeholders */}<Trans>Click <0>here</0> to continue</Trans>{/* Translators see: Click {0} to continue */}<!-- Real HTML elements — no indices, no XSS --><Trans>Click <a href="/docs">here</a> to continue</Trans>Fluenti preserves your actual markup. Translators see HTML they already understand, and there is no XSS vector.
How Fluenti compares
Section titled “How Fluenti compares”| Feature | vue-i18n | Lingui | Fluenti |
|---|---|---|---|
| Keys | Manual key strings | Auto-generated IDs | Source text = key |
| Rich text | v-html (XSS risk) | <0>indexed</0> placeholders | Native <a>, <strong>, etc. |
| Runtime cost | Full parser in bundle | Compiled messages | Compiled + v-t zero-cost |
| Code splitting | Manual | Per-route | Per-route (built-in) |
| Catalog format | JSON only | PO / JSON | PO / JSON |
| SSR | Plugin config required | Custom setup | Built-in locale detection |
| Frameworks | Vue only | React only | Vue, Solid, and more |
| ICU MessageFormat | Partial support | Full | Full |
| Formatters | Separate @intlify/core | External packages | Built-in d() / n() |
Architecture overview
Section titled “Architecture overview”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 │ └──────────┘ └──────────┘ └──────────────────────────┘-
Write source text directly in your templates:
<h1 v-t>Welcome</h1>ort('Hello!') -
Extract messages with
fluenti extract— scans Vue SFCs and TSX files, generates PO catalogs -
Translate using any gettext-compatible tool (Poedit, Crowdin, Weblate) or translate the PO files by hand
-
Compile with
fluenti compile— generates optimized JS modules, one per locale, ready for code splitting -
Ship — Vite bundles compiled translations automatically via
@fluenti/vite-plugin, lazy-loading per route
Packages
Section titled “Packages”| Package | Description |
|---|---|
@fluenti/core | Framework-agnostic ICU parser, compiler, interpolation, plural/select, and formatters |
@fluenti/vue | Vue 3 plugin: v-t directive, <Trans>, <Plural>, <Select>, useI18n() composable |
@fluenti/solid | SolidJS integration: I18nProvider, <Trans>, <Plural>, <Select>, useI18n() hook |
@fluenti/cli | Message extraction (Vue SFC + TSX), PO/JSON catalog format, compilation |
@fluenti/vite-plugin | Vite plugin: virtual modules, build-time v-t transforms, per-route code splitting |
Installation
Section titled “Installation”pnpm add @fluenti/core @fluenti/vuepnpm add -D @fluenti/cli @fluenti/vite-pluginnpm install @fluenti/core @fluenti/vuenpm install -D @fluenti/cli @fluenti/vite-pluginSolidJS
Section titled “SolidJS”pnpm add @fluenti/core @fluenti/solidpnpm add -D @fluenti/cli @fluenti/vite-pluginnpm install @fluenti/core @fluenti/solidnpm install -D @fluenti/cli @fluenti/vite-pluginRequirements
Section titled “Requirements”- Node.js >= 18
- Vue >= 3.4 (for Vue bindings)
- SolidJS >= 1.8 (for Solid bindings)
- Vite >= 5 (for Vite plugin)
Next steps
Section titled “Next steps”- Quick Start (Vue) — build your first translated Vue app
- Quick Start (SolidJS) — build your first translated Solid app
- The v-t directive — deep dive into compile-time transforms
- Components — Trans, Plural, and Select components