@zairakai/js-i18n
v1.0.1
Published
Lightweight internationalization library with Laravel-style translation, pluralization, dot-notation keys, and multi-locale support
Downloads
107
Maintainers
Readme
@zairakai/js-i18n
Lightweight internationalization library with Laravel-style translation, pluralization, dot-notation keys, and multi-locale support.
Features
- Laravel-style
__()— familiar:attributereplacement and{0} | {1} | [2,*] :countpluralization - Dot notation keys — navigate nested translation objects with
auth.login.title - Multi-locale — manage any number of locales, switch at runtime
- Runtime validation — translation data validated at runtime, invalid structures throw with a descriptive error message
- Type-safe — full TypeScript types for IDE support and static analysis
Install
npm install @zairakai/js-i18nUsage
Basic translation
import { createI18n } from '@zairakai/js-i18n'
const i18n = createI18n(
{
en: {
welcome: 'Welcome, :name!',
auth: {
login: 'Sign in',
logout: 'Sign out',
},
},
fr: {
welcome: 'Bienvenue, :name !',
auth: {
login: 'Se connecter',
logout: 'Se déconnecter',
},
},
},
'en'
)
i18n.__('welcome', { name: 'Stan' }) // "Welcome, Stan!"
i18n.__('auth.login') // "Sign in"Pluralization
import { createI18n } from '@zairakai/js-i18n'
const i18n = createI18n({
en: {
apples: '{0} No apples|{1} One apple|[2,*] :count apples',
files: '[0,1] :count file|[2,*] :count files',
},
})
i18n.__('apples', 0) // "No apples"
i18n.__('apples', 1) // "One apple"
i18n.__('apples', 5) // "5 apples"Count + replacements (case 3)
i18n.__('files', 3, { extra: 'info' }) // "3 files"Managing locales at runtime
i18n.setLocale('fr')
i18n.getLocale() // "fr"
i18n.getAvailableLocales() // ["en", "fr"]
i18n.setTranslations('de', { welcome: 'Willkommen, :name!' })
i18n.addTranslations('de', { auth: { login: 'Anmelden' } })
i18n.hasTranslation('auth.login', 'de') // true
i18n.hasTranslation('auth.logout', 'de') // falseError handling
Translation data is validated at runtime. Invalid structures (e.g. loading from an API or external JSON) throw an Error with a descriptive message indicating exactly what is wrong.
import { createI18n } from '@zairakai/js-i18n'
try {
const data = await fetchTranslations() // unknown external data
const i18n = createI18n(data, 'en')
} catch (e) {
// e.message describes the invalid field and its path
console.error('Invalid translation data:', (e as Error).message)
}The same applies to setTranslations(), addTranslations(), and translate() when replacements are malformed.
Pluralization syntax
The pluralization format follows Laravel's trans_choice pattern exactly.
| Pattern | Matches | Example |
| --------------- | ---------------------------- | ------------------------------------ |
| {0} | Exactly 0 | {0} No items |
| {1} | Exactly 1 | {1} One item |
| {n} | Exactly n | {5} Exactly five |
| [2,*] | 2 and above | [2,*] :count items |
| [0,1] | 0 or 1 | [0,1] :count file |
| [1,10] | Between 1 and 10 (inclusive) | [1,10] a few items |
Forms are separated by |. The :count placeholder is automatically replaced by the count value.
// Full example
'{0} No apples|{1} One apple|[2,*] :count apples'API Reference
Factory functions
| Function | Description |
| --- | --- |
| createI18n(translations?, locale?) | Creates a translator instance (alias, preferred). |
| createTranslator(translations?, locale?) | Creates a translator instance (explicit name). |
Both return a Translator instance. Default locale is 'en'.
Translator methods
| Method | Description |
| --------------------------------------- | ------------------------------------------------------- |
| __(path, replacements?) | Translate a key with optional replacements. |
| __(path, count, replacements?) | Translate with pluralization count. |
| translate(path, replacements?) | Alias for __. |
| translate(path, count, replacements?) | Alias for __ with count. |
| setLocale(locale) | Set the active locale. |
| getLocale() | Get the active locale. |
| setTranslations(locale, translations) | Replace all translations for a locale. |
| addTranslations(locale, translations) | Merge translations into an existing locale. |
| hasTranslation(path, locale?) | Check if a translation key exists (uses active locale). |
| getAvailableLocales() | Return all registered locale codes. |
Pluralization utilities
| Function | Description |
| ---------------------------------- | ----------------------------------------------- |
| applyPluralization(value, count) | Apply pluralization to a raw string with count. |
| selectPluralForm(forms, count) | Select the correct form from a pre-split array. |
Development
npm install # install dependencies
make quality # full quality gate (lint, format, typecheck, tests)
make test # run vitest
make test-coverage # run vitest with coverage
make ci # run CI validation locallySee CONTRIBUTING.md for the full development workflow.
Getting Help
Made with ❤️ by Zairakai
