A tiny, framework-agnostic translation library for TypeScript. Pluggable stores, BCP-47 fallback chains, ICU-lite plurals, Intl-powered formatters — all in a few kilobytes.
chain: en
Every layer is replaceable, every contract is documented, every line is typed.
Two-dependency runtime, ESM-only, browser-safe. Ships in kilobytes, not megabytes.
A 3-method IStore port — in-memory by default, file-system adapter included, write your own in a few lines.
Locale-first resolution walks pt-BR → pt → en automatically. Override with a string, array, function, or opt out.
Intl.PluralRules-backed selection over CLDR categories. Explicit @plural marker keeps namespaces unambiguous.
Inline {{value, number(...)}}, date, and list modifiers — all locale-aware, all memoised per instance.
defineCatalog() captures literal shapes; Ilingo<typeof catalog> refuses typos and requires count on plural keys.
Same core, three flavours. Mix and match — they all wrap the same Ilingo orchestrator.
Lazy-load translations from the file system, write them back as JSON.
Vue 3 plugin with reactive locale, composable, and component.
Drop-in messages for Vuelidate validators.
Three steps. No decorators, no compiler plugins, no build-time codegen.
npm install ilingo
# Optional adapters
npm install @ilingo/fs # load locales from disk
npm install @ilingo/vue # Vue 3 plugin
npm install @ilingo/vuelidate # Vuelidate validator messages A drop-in plugin that wires provide / inject for the Ilingo instance and a reactive locale Ref — plus a useTranslation composable and an <ITranslate> component.
install() any number of times — it merges into an existing instance instead of clobbering it.<script setup>
import { injectLocale, useTranslation } from '@ilingo/vue';
const locale = injectLocale();
const greeting = useTranslation({
group: 'cart',
key: 'greeting',
data: { name: 'Paul' },
});
const items = useTranslation({
group: 'cart',
key: 'items',
count: 3,
});
</script>
<template>
<button @click="locale = 'de'">DE</button>
<button @click="locale = 'en'">EN</button>
<p>{{ greeting }}</p>
<p>{{ items }}</p>
<ITranslate path="cart.greeting" :data="{ name: 'Peter' }" />
</template>